@wandelbots/wandelbots-js-react-components 1.3.0 → 1.3.2

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 (168) hide show
  1. package/README.md +0 -29
  2. package/package.json +60 -43
  3. package/src/components/3d-viewport/CoordinateSystemTransform.tsx +44 -0
  4. package/src/components/3d-viewport/PresetEnvironment.tsx +78 -0
  5. package/src/components/3d-viewport/SafetyZonesRenderer.tsx +54 -0
  6. package/src/components/LoadingButton.stories.tsx +61 -0
  7. package/src/components/LoadingButton.tsx +19 -0
  8. package/src/components/LoadingCover.tsx +75 -0
  9. package/src/components/ThemeSelect.tsx +49 -0
  10. package/src/components/VelocitySlider.stories.tsx +32 -0
  11. package/src/components/VelocitySlider.tsx +52 -0
  12. package/src/components/jogging/JoggingCartesianAxisControl.stories.tsx +41 -0
  13. package/src/components/jogging/JoggingCartesianAxisControl.tsx +127 -0
  14. package/src/components/jogging/JoggingCartesianTab.tsx +265 -0
  15. package/src/components/jogging/JoggingCartesianValues.tsx +45 -0
  16. package/src/components/jogging/JoggingFreedriveTab.tsx +9 -0
  17. package/src/components/jogging/JoggingJointLimitDetector.tsx +51 -0
  18. package/src/components/jogging/JoggingJointRotationControl.stories.tsx +38 -0
  19. package/src/components/jogging/JoggingJointRotationControl.tsx +197 -0
  20. package/src/components/jogging/JoggingJointTab.tsx +93 -0
  21. package/src/components/jogging/JoggingJointValues.tsx +45 -0
  22. package/src/components/jogging/JoggingOptions.tsx +96 -0
  23. package/src/components/jogging/JoggingPanel.stories.tsx +26 -0
  24. package/src/components/jogging/JoggingPanel.tsx +148 -0
  25. package/src/components/jogging/JoggingStore.tsx +294 -0
  26. package/src/components/jogging/JoggingVelocitySlider.tsx +56 -0
  27. package/src/components/robots/ABB_1200_07_7.tsx +123 -0
  28. package/src/components/robots/AxisConfig.ts +3 -0
  29. package/src/components/robots/DHRobot.tsx +129 -0
  30. package/src/components/robots/FANUC_ARC_Mate_100iD.tsx +187 -0
  31. package/src/components/robots/FANUC_ARC_Mate_120iD.tsx +187 -0
  32. package/src/components/robots/FANUC_CRX10iA.tsx +167 -0
  33. package/src/components/robots/FANUC_CRX25iA.tsx +167 -0
  34. package/src/components/robots/FANUC_CRX25iAL.tsx +178 -0
  35. package/src/components/robots/KUKA_KR210_R2700.tsx +291 -0
  36. package/src/components/robots/KUKA_KR270_R2700.tsx +244 -0
  37. package/src/components/robots/RobotAnimator.tsx +83 -0
  38. package/src/components/robots/SupportedRobot.tsx +131 -0
  39. package/src/components/robots/UniversalRobots_UR10.tsx +112 -0
  40. package/src/components/robots/UniversalRobots_UR10e.tsx +275 -0
  41. package/src/components/robots/UniversalRobots_UR3.tsx +112 -0
  42. package/src/components/robots/UniversalRobots_UR3e.tsx +112 -0
  43. package/src/components/robots/UniversalRobots_UR5.tsx +111 -0
  44. package/src/components/robots/UniversalRobots_UR5e.tsx +280 -0
  45. package/src/components/robots/Yaskawa_AR1440.tsx +152 -0
  46. package/src/components/robots/Yaskawa_AR1730.tsx +165 -0
  47. package/src/components/robots/Yaskawa_AR2010.tsx +159 -0
  48. package/src/components/robots/Yaskawa_AR3120.tsx +160 -0
  49. package/src/components/robots/Yaskawa_AR900.tsx +121 -0
  50. package/src/components/utils/converters.ts +23 -0
  51. package/src/components/utils/errorHandling.ts +30 -0
  52. package/src/components/utils/hooks.tsx +54 -0
  53. package/src/components/utils/robotTreeQuery.ts +27 -0
  54. package/src/components/wandelscript-editor/WandelscriptEditor.stories.tsx +45 -0
  55. package/src/components/wandelscript-editor/WandelscriptEditor.tsx +114 -0
  56. package/src/components/wandelscript-editor/wandelscript.tmLanguage.ts +62 -0
  57. package/src/declarations.d.ts +10 -0
  58. package/src/i18n/config.ts +27 -0
  59. package/src/i18n/locales/de/translations.json +12 -0
  60. package/src/i18n/locales/en/translations.json +12 -0
  61. package/src/icons/arrowForwardFilled.tsx +7 -0
  62. package/src/icons/axis-x.svg +3 -0
  63. package/src/icons/axis-y.svg +3 -0
  64. package/src/icons/axis-z.svg +3 -0
  65. package/src/icons/expandFilled.tsx +11 -0
  66. package/src/icons/home.tsx +12 -0
  67. package/src/icons/infoOutlined.tsx +10 -0
  68. package/src/icons/jogging.svg +3 -0
  69. package/src/icons/robot.svg +3 -0
  70. package/src/icons/robot.tsx +14 -0
  71. package/src/icons/rotation.svg +4 -0
  72. package/src/icons/wbLogo.tsx +21 -0
  73. package/src/index.ts +7 -0
  74. package/src/themes/color.tsx +74 -0
  75. package/src/themes/theme.ts +150 -0
  76. package/src/themes/wbTheme.stories.tsx +64 -0
  77. package/src/themes/wbTheme.ts +186 -0
  78. package/dist/cjs/components/3d-viewport/SafetyZonesRenderer.d.ts +0 -2
  79. package/dist/cjs/index.js +0 -5875
  80. package/dist/cjs/types/components/3d-viewport/CoordinateSystemTransform.d.ts +0 -10
  81. package/dist/cjs/types/components/3d-viewport/PresetEnvironment.d.ts +0 -6
  82. package/dist/cjs/types/components/3d-viewport/SafetyZonesRenderer.d.ts +0 -6
  83. package/dist/cjs/types/components/robots/ABB_1200_07_7.d.ts +0 -2
  84. package/dist/cjs/types/components/robots/AxisConfig.d.ts +0 -2
  85. package/dist/cjs/types/components/robots/DHRobot.d.ts +0 -2
  86. package/dist/cjs/types/components/robots/FANUC_ARC_Mate_100iD.d.ts +0 -2
  87. package/dist/cjs/types/components/robots/FANUC_ARC_Mate_120iD.d.ts +0 -2
  88. package/dist/cjs/types/components/robots/FANUC_CRX10iA.d.ts +0 -2
  89. package/dist/cjs/types/components/robots/FANUC_CRX25iA.d.ts +0 -2
  90. package/dist/cjs/types/components/robots/FANUC_CRX25iAL.d.ts +0 -2
  91. package/dist/cjs/types/components/robots/KUKA_KR210_R2700.d.ts +0 -2
  92. package/dist/cjs/types/components/robots/KUKA_KR270_R2700.d.ts +0 -2
  93. package/dist/cjs/types/components/robots/RobotAnimator.d.ts +0 -11
  94. package/dist/cjs/types/components/robots/SupportedRobot.d.ts +0 -14
  95. package/dist/cjs/types/components/robots/UniversalRobots_UR10.d.ts +0 -2
  96. package/dist/cjs/types/components/robots/UniversalRobots_UR10e.d.ts +0 -2
  97. package/dist/cjs/types/components/robots/UniversalRobots_UR3.d.ts +0 -2
  98. package/dist/cjs/types/components/robots/UniversalRobots_UR3e.d.ts +0 -2
  99. package/dist/cjs/types/components/robots/UniversalRobots_UR5.d.ts +0 -2
  100. package/dist/cjs/types/components/robots/UniversalRobots_UR5e.d.ts +0 -2
  101. package/dist/cjs/types/components/robots/Yaskawa_AR1440.d.ts +0 -2
  102. package/dist/cjs/types/components/robots/Yaskawa_AR1730.d.ts +0 -2
  103. package/dist/cjs/types/components/robots/Yaskawa_AR2010.d.ts +0 -2
  104. package/dist/cjs/types/components/robots/Yaskawa_AR3120.d.ts +0 -2
  105. package/dist/cjs/types/components/robots/Yaskawa_AR900.d.ts +0 -2
  106. package/dist/cjs/types/components/utils/hooks.d.ts +0 -21
  107. package/dist/cjs/types/components/utils/robotTreeQuery.d.ts +0 -5
  108. package/dist/cjs/types/components/wandelscript-editor/WandelscriptEditor.d.ts +0 -12
  109. package/dist/cjs/types/components/wandelscript-editor/WandelscriptEditor.stories.d.ts +0 -5
  110. package/dist/cjs/types/components/wandelscript-editor/wandelscript.tmLanguage.d.ts +0 -44
  111. package/dist/cjs/types/icons/arrowForwardFilled.d.ts +0 -1
  112. package/dist/cjs/types/icons/expandFilled.d.ts +0 -1
  113. package/dist/cjs/types/icons/home.d.ts +0 -1
  114. package/dist/cjs/types/icons/infoOutlined.d.ts +0 -1
  115. package/dist/cjs/types/icons/robot.d.ts +0 -1
  116. package/dist/cjs/types/icons/wbLogo.d.ts +0 -6
  117. package/dist/cjs/types/index.d.ts +0 -4
  118. package/dist/cjs/types/themes/color.d.ts +0 -9
  119. package/dist/cjs/types/themes/theme.d.ts +0 -143
  120. package/dist/cjs/types/themes/wbTheme.d.ts +0 -1
  121. package/dist/cjs/types/themes/wbTheme.stories.d.ts +0 -6
  122. package/dist/esm/components/3d-viewport/SafetyZonesRenderer.d.ts +0 -2
  123. package/dist/esm/index.js +0 -5852
  124. package/dist/esm/types/components/3d-viewport/CoordinateSystemTransform.d.ts +0 -10
  125. package/dist/esm/types/components/3d-viewport/PresetEnvironment.d.ts +0 -6
  126. package/dist/esm/types/components/3d-viewport/SafetyZonesRenderer.d.ts +0 -6
  127. package/dist/esm/types/components/robots/ABB_1200_07_7.d.ts +0 -2
  128. package/dist/esm/types/components/robots/AxisConfig.d.ts +0 -2
  129. package/dist/esm/types/components/robots/DHRobot.d.ts +0 -2
  130. package/dist/esm/types/components/robots/FANUC_ARC_Mate_100iD.d.ts +0 -2
  131. package/dist/esm/types/components/robots/FANUC_ARC_Mate_120iD.d.ts +0 -2
  132. package/dist/esm/types/components/robots/FANUC_CRX10iA.d.ts +0 -2
  133. package/dist/esm/types/components/robots/FANUC_CRX25iA.d.ts +0 -2
  134. package/dist/esm/types/components/robots/FANUC_CRX25iAL.d.ts +0 -2
  135. package/dist/esm/types/components/robots/KUKA_KR210_R2700.d.ts +0 -2
  136. package/dist/esm/types/components/robots/KUKA_KR270_R2700.d.ts +0 -2
  137. package/dist/esm/types/components/robots/RobotAnimator.d.ts +0 -11
  138. package/dist/esm/types/components/robots/SupportedRobot.d.ts +0 -14
  139. package/dist/esm/types/components/robots/UniversalRobots_UR10.d.ts +0 -2
  140. package/dist/esm/types/components/robots/UniversalRobots_UR10e.d.ts +0 -2
  141. package/dist/esm/types/components/robots/UniversalRobots_UR3.d.ts +0 -2
  142. package/dist/esm/types/components/robots/UniversalRobots_UR3e.d.ts +0 -2
  143. package/dist/esm/types/components/robots/UniversalRobots_UR5.d.ts +0 -2
  144. package/dist/esm/types/components/robots/UniversalRobots_UR5e.d.ts +0 -2
  145. package/dist/esm/types/components/robots/Yaskawa_AR1440.d.ts +0 -2
  146. package/dist/esm/types/components/robots/Yaskawa_AR1730.d.ts +0 -2
  147. package/dist/esm/types/components/robots/Yaskawa_AR2010.d.ts +0 -2
  148. package/dist/esm/types/components/robots/Yaskawa_AR3120.d.ts +0 -2
  149. package/dist/esm/types/components/robots/Yaskawa_AR900.d.ts +0 -2
  150. package/dist/esm/types/components/utils/hooks.d.ts +0 -21
  151. package/dist/esm/types/components/utils/robotTreeQuery.d.ts +0 -5
  152. package/dist/esm/types/components/wandelscript-editor/WandelscriptEditor.d.ts +0 -12
  153. package/dist/esm/types/components/wandelscript-editor/WandelscriptEditor.stories.d.ts +0 -5
  154. package/dist/esm/types/components/wandelscript-editor/wandelscript.tmLanguage.d.ts +0 -44
  155. package/dist/esm/types/icons/arrowForwardFilled.d.ts +0 -1
  156. package/dist/esm/types/icons/expandFilled.d.ts +0 -1
  157. package/dist/esm/types/icons/home.d.ts +0 -1
  158. package/dist/esm/types/icons/index.d.ts +0 -6
  159. package/dist/esm/types/icons/infoOutlined.d.ts +0 -1
  160. package/dist/esm/types/icons/robot.d.ts +0 -1
  161. package/dist/esm/types/icons/wbLogo.d.ts +0 -6
  162. package/dist/esm/types/index.d.ts +0 -4
  163. package/dist/esm/types/themes/color.d.ts +0 -9
  164. package/dist/esm/types/themes/theme.d.ts +0 -143
  165. package/dist/esm/types/themes/wbTheme.d.ts +0 -1
  166. package/dist/esm/types/themes/wbTheme.stories.d.ts +0 -6
  167. package/dist/index.d.ts +0 -33
  168. /package/{dist/cjs/types/icons/index.d.ts → src/icons/index.ts} +0 -0
@@ -0,0 +1,294 @@
1
+ import { keyBy } from "lodash-es"
2
+ import { autorun, makeAutoObservable, type IReactionDisposer } from "mobx"
3
+ import type { CoordinateSystem, JoggerConnection, MotionGroupSpecification, RobotTcp } from "@wandelbots/wandelbots-js"
4
+ import { tryParseJson } from "@wandelbots/wandelbots-js"
5
+
6
+ const discreteIncrementOptions = [
7
+ { id: "0.1", mm: 0.1, degrees: 0.05 },
8
+ { id: "1", mm: 1, degrees: 0.5 },
9
+ { id: "5", mm: 5, degrees: 2.5 },
10
+ { id: "10", mm: 10, degrees: 5 },
11
+ ]
12
+
13
+ const incrementOptions = [
14
+ { id: "continuous" },
15
+ ...discreteIncrementOptions,
16
+ ] as const
17
+
18
+ export type DiscreteIncrementOption = (typeof discreteIncrementOptions)[number]
19
+ export type IncrementOption = (typeof incrementOptions)[number]
20
+ export type IncrementOptionId = IncrementOption["id"]
21
+
22
+ export class JoggingStore {
23
+ selectedTabId: "cartesian" | "joint" | "debug" = "cartesian"
24
+
25
+ // TODO
26
+ isLocked: boolean = false
27
+
28
+ /**
29
+ * Id of selected coordinate system from among those defined on the API side
30
+ */
31
+ selectedCoordSystemId: string = "world"
32
+
33
+ /** Id of selected tool center point from among the options available on the robot */
34
+ selectedTcpId: string = ""
35
+
36
+ /**
37
+ * Id of selected increment amount for jogging. Options are defined by robot pad.
38
+ * When non-continuous, jogging moves the robot by a fixed number of mm or degrees
39
+ * each time the button is pressed, for extra precision
40
+ */
41
+ selectedIncrementId: IncrementOptionId = "continuous"
42
+
43
+ /**
44
+ * When on the cartesian tab, jogging can be either translating or rotating
45
+ * around the TCP.
46
+ */
47
+ selectedCartesianMotionType: "translate" | "rotate" = "translate"
48
+
49
+ /** True when the API is busy doing a planned increment jog motion */
50
+ incrementJoggingInProgress = false
51
+
52
+ /** How fast the robot goes when doing cartesian translate jogging in mm/s */
53
+ translationVelocityMmPerSec: number = 10
54
+ /** How fast the robot goes when doing cartesian or joint rotation jogging in °/s */
55
+ rotationVelocityDegPerSec: number = 1
56
+
57
+ /** Minimum translation velocity user can choose on the velocity slider in °/s */
58
+ minTranslationVelocityMmPerSec: number = 5
59
+ /** Maximum translation velocity user can choose on the velocity slider in °/s */
60
+ maxTranslationVelocityMmPerSec: number = 250
61
+
62
+ /** Minimum rotation velocity user can choose on the velocity slider in °/s */
63
+ minRotationVelocityDegPerSec: number = 1
64
+ /** Maximum rotation velocity user can choose on the velocity slider in °/s */
65
+ maxRotationVelocityDegPerSec: number = 60
66
+
67
+ disposers: IReactionDisposer[] = []
68
+
69
+ /**
70
+ * Load a jogging store with the relevant data it needs
71
+ * from the backend
72
+ */
73
+ static async loadFor(jogger: JoggerConnection) {
74
+ const { nova } = jogger
75
+
76
+ // Find out what TCPs this motion group has (we need it for jogging)
77
+ const [motionGroupSpec, { coordinatesystems }, { tcps }] = await Promise.all([
78
+ nova.api.motionGroupInfos.getMotionGroupSpecification(jogger.motionGroupId),
79
+
80
+ // Fetch coord systems so user can select between them
81
+ nova.api.coordinateSystems.listCoordinateSystems("ROTATION_VECTOR"),
82
+
83
+ // Same for TCPs
84
+ nova.api.motionGroupInfos.listTcps(
85
+ jogger.motionGroupId,
86
+ "ROTATION_VECTOR",
87
+ ),
88
+ ])
89
+
90
+ return new JoggingStore(jogger, motionGroupSpec, coordinatesystems || [], tcps || [])
91
+ }
92
+
93
+ constructor(
94
+ readonly jogger: JoggerConnection,
95
+ readonly motionGroupSpec: MotionGroupSpecification,
96
+ readonly coordSystems: CoordinateSystem[],
97
+ readonly tcps: RobotTcp[],
98
+ ) {
99
+ // TODO workaround for default coord system on backend having a canonical id
100
+ // of empty string. Can remove when fixed on API side
101
+ for (const cs of coordSystems) {
102
+ if (cs.coordinate_system === "") {
103
+ cs.coordinate_system = "world"
104
+ break
105
+ }
106
+ }
107
+ this.selectedCoordSystemId = coordSystems[0]?.coordinate_system || "world"
108
+ this.selectedTcpId = tcps[0]?.id || ""
109
+
110
+ makeAutoObservable(this, {}, { autoBind: true })
111
+
112
+ // Load user settings from local storage if available
113
+ this.loadFromLocalStorage()
114
+
115
+ // Automatically save user settings to local storage when save changes
116
+ this.disposers.push(autorun(() => this.saveToLocalStorage()))
117
+ ;(window as any).joggingStore = this
118
+ }
119
+
120
+ dispose() {
121
+ for (const dispose of this.disposers) {
122
+ dispose()
123
+ }
124
+ this.jogger.dispose()
125
+ }
126
+
127
+ loadFromLocalStorage() {
128
+ const save = tryParseJson(localStorage.getItem("joggingToolStore"))
129
+ if (!save) return
130
+
131
+ if (this.tabsById[save.selectedTabId]) {
132
+ this.selectedTabId = save.selectedTabId
133
+ }
134
+
135
+ if (this.coordSystemsById[save.selectedCoordSystemId]) {
136
+ this.selectedCoordSystemId = save.selectedCoordSystemId
137
+ }
138
+
139
+ if (this.tcpsById[save.selectedTcpId]) {
140
+ this.selectedTcpId = save.selectedTcpId
141
+ }
142
+
143
+ if (this.incrementOptionsById[save.selectedIncrementId]) {
144
+ this.selectedIncrementId = save.selectedIncrementId
145
+ }
146
+
147
+ if (["translate", "rotate"].includes(save.selectedCartesianMotionType)) {
148
+ this.selectedCartesianMotionType = save.selectedCartesianMotionType
149
+ }
150
+ }
151
+
152
+ saveToLocalStorage() {
153
+ localStorage.setItem(
154
+ "joggingToolStore",
155
+ JSON.stringify(this.localStorageSave),
156
+ )
157
+ }
158
+
159
+ get localStorageSave() {
160
+ return {
161
+ selectedTabId: this.selectedTabId,
162
+ selectedCoordSystemId: this.selectedCoordSystemId,
163
+ selectedTcpId: this.selectedTcpId,
164
+ selectedIncrementId: this.selectedIncrementId,
165
+ selectedCartesianMotionType: this.selectedCartesianMotionType,
166
+ }
167
+ }
168
+
169
+ get tabs() {
170
+ return [
171
+ {
172
+ id: "cartesian",
173
+ label: "Cartesian",
174
+ },
175
+ {
176
+ id: "joint",
177
+ label: "Joint",
178
+ },
179
+ ] as const
180
+ }
181
+
182
+ get incrementOptions() {
183
+ return incrementOptions
184
+ }
185
+
186
+ get discreteIncrementOptions() {
187
+ return discreteIncrementOptions
188
+ }
189
+
190
+ get incrementOptionsById() {
191
+ return keyBy(this.incrementOptions, (o) => o.id)
192
+ }
193
+
194
+ get tabsById() {
195
+ return keyBy(this.tabs, (t) => t.id)
196
+ }
197
+
198
+ get currentTab() {
199
+ return this.tabsById[this.selectedTabId] || this.tabs[0]!
200
+ }
201
+
202
+ get tabIndex() {
203
+ return this.tabs.indexOf(this.currentTab)
204
+ }
205
+
206
+ get coordSystemsById() {
207
+ return keyBy(this.coordSystems, (cs) => cs.coordinate_system)
208
+ }
209
+
210
+ get selectedCoordSystem() {
211
+ return this.coordSystemsById[this.selectedCoordSystemId]
212
+ }
213
+
214
+ get tcpsById() {
215
+ return keyBy(this.tcps, (tcp) => tcp.id)
216
+ }
217
+
218
+ get selectedDiscreteIncrement() {
219
+ return discreteIncrementOptions.find(
220
+ (d) => d.id === this.selectedIncrementId,
221
+ )
222
+ }
223
+
224
+ /** The selected rotation velocity converted to radians per second */
225
+ get rotationVelocityRadsPerSec() {
226
+ return (this.rotationVelocityDegPerSec * Math.PI) / 180
227
+ }
228
+
229
+ get velocityInCurrentUnits() {
230
+ return this.currentMotionType === "translate"
231
+ ? this.translationVelocityMmPerSec
232
+ : this.rotationVelocityDegPerSec
233
+ }
234
+
235
+ get minVelocityInCurrentUnits() {
236
+ return this.currentMotionType === "translate"
237
+ ? this.minTranslationVelocityMmPerSec
238
+ : this.minRotationVelocityDegPerSec
239
+ }
240
+
241
+ get maxVelocityInCurrentUnits() {
242
+ return this.currentMotionType === "translate"
243
+ ? this.maxTranslationVelocityMmPerSec
244
+ : this.maxRotationVelocityDegPerSec
245
+ }
246
+
247
+ /**
248
+ * For velocity unit purposes, joint and cartesian rotation
249
+ * are treated as the same type of motion
250
+ */
251
+ get currentMotionType() {
252
+ if (
253
+ this.selectedTabId === "cartesian" &&
254
+ this.selectedCartesianMotionType === "translate"
255
+ ) {
256
+ return "translate"
257
+ } else {
258
+ return "rotate"
259
+ }
260
+ }
261
+
262
+ onTabChange(_event: React.SyntheticEvent, newValue: number) {
263
+ const tab = this.tabs[newValue] || this.tabs[0]!
264
+ this.selectedTabId = tab.id
265
+ }
266
+
267
+ setSelectedCoordSystemId(id: string) {
268
+ this.selectedCoordSystemId = id
269
+ }
270
+
271
+ setSelectedTcpId(id: string) {
272
+ this.selectedTcpId = id
273
+ }
274
+
275
+ setSelectedIncrementId(id: IncrementOptionId) {
276
+ this.selectedIncrementId = id
277
+ }
278
+
279
+ setIncrementJoggingInProgress(inProgress: boolean) {
280
+ this.incrementJoggingInProgress = inProgress
281
+ }
282
+
283
+ setVelocityFromSlider(velocity: number) {
284
+ if (this.currentMotionType === "translate") {
285
+ this.translationVelocityMmPerSec = velocity
286
+ } else {
287
+ this.rotationVelocityDegPerSec = velocity
288
+ }
289
+ }
290
+
291
+ setSelectedCartesianMotionType(type: "translate" | "rotate") {
292
+ this.selectedCartesianMotionType = type
293
+ }
294
+ }
@@ -0,0 +1,56 @@
1
+ import { Stack, Divider, Typography } from "@mui/material"
2
+ import { observer, useLocalObservable } from "mobx-react-lite"
3
+ import type { JoggingStore } from "./JoggingStore"
4
+ import { VelocitySlider } from "../VelocitySlider"
5
+ import { useTranslation } from "react-i18next"
6
+
7
+ export const JoggingVelocitySlider = observer(
8
+ ({ store }: { store: JoggingStore }) => {
9
+ const { t } = useTranslation()
10
+
11
+ const state = useLocalObservable(() => ({
12
+ get valueLabelFormat() {
13
+ if (store.currentMotionType === "translate") {
14
+ return (value: number) =>
15
+ `v=${t("Jogging.Cartesian.Translation.velocityMmPerSec.lb", { amount: value })}`
16
+ } else {
17
+ return (value: number) =>
18
+ `v=${t("Jogging.Cartesian.Rotation.velocityDegPerSec.lb", { amount: value })}`
19
+ }
20
+ },
21
+ }))
22
+
23
+ return (
24
+ <Stack>
25
+ <Divider />
26
+ <Stack
27
+ sx={{
28
+ margin: "0px 20px",
29
+ marginTop: "0.8rem",
30
+ marginBottom: "0.8rem",
31
+ }}
32
+ >
33
+ <Stack sx={{ width: "380px", maxWidth: "90%", margin: "auto" }}>
34
+ <Typography
35
+ sx={{
36
+ fontWeight: "bold",
37
+ fontSize: "15px",
38
+ }}
39
+ >
40
+ {t("Jogging.Velocity.lb")}
41
+ </Typography>
42
+ <VelocitySlider
43
+ velocity={store.velocityInCurrentUnits}
44
+ min={store.minVelocityInCurrentUnits}
45
+ max={store.maxVelocityInCurrentUnits}
46
+ onVelocityChange={store.setVelocityFromSlider}
47
+ disabled={store.isLocked}
48
+ valueLabelFormat={state.valueLabelFormat}
49
+ />
50
+ </Stack>
51
+ </Stack>
52
+ <Divider />
53
+ </Stack>
54
+ )
55
+ },
56
+ )
@@ -0,0 +1,123 @@
1
+ import { useGLTF } from "@react-three/drei"
2
+ import type * as THREE from "three"
3
+ import type { RobotProps } from "./SupportedRobot"
4
+ import { animated } from "@react-spring/three"
5
+ import RobotAnimator from "./RobotAnimator"
6
+
7
+ export function ABB_1200_07_7({ modelURL, connectedMotionGroup, ...props }: RobotProps) {
8
+ const gltf = useGLTF(modelURL) as any
9
+ const nodes = gltf.nodes
10
+ const materials = gltf.materials
11
+ const rotationOffsets = [0, -Math.PI / 2, 0, 0, 0, 0]
12
+
13
+ function setRotation(jointObjects: THREE.Object3D[], jointValues: number[]) {
14
+ jointObjects.forEach(
15
+ (object, index) =>
16
+ (object.rotation.y = jointValues[index]! + rotationOffsets[index]!),
17
+ )
18
+ }
19
+
20
+ return (
21
+ <>
22
+ <RobotAnimator
23
+ connectedMotionGroup={connectedMotionGroup}
24
+ robotRootObjectName="Scene"
25
+ onRotationChanged={setRotation}
26
+ />
27
+ <group {...props} dispose={null}>
28
+ <group name="Scene">
29
+ <group name="IRB1200_7_70_IRC5" rotation={[Math.PI / 2, 0, 0]}>
30
+ <animated.group
31
+ name="IRB1200_7_70_IRC5_J01"
32
+ rotation={[-Math.PI / 2, 0, 0]}
33
+ >
34
+ <animated.group
35
+ name="IRB1200_7_70_IRC5_J02"
36
+ position={[0, 0.399, 0]}
37
+ rotation={[-Math.PI / 2, -Math.PI / 2, 0]}
38
+ >
39
+ <animated.group
40
+ name="IRB1200_7_70_IRC5_J03"
41
+ position={[0.35, 0, 0]}
42
+ >
43
+ <animated.group
44
+ name="IRB1200_7_70_IRC5_J04"
45
+ position={[0.042, 0, 0]}
46
+ rotation={[-Math.PI / 2, 0, 0]}
47
+ >
48
+ <animated.group
49
+ name="IRB1200_7_70_IRC5_J05"
50
+ position={[0, 0.351, 0]}
51
+ rotation={[Math.PI / 2, 0, 0]}
52
+ >
53
+ <animated.group
54
+ name="IRB1200_7_70_IRC5_J06"
55
+ rotation={[Math.PI / 2, 0, -Math.PI]}
56
+ >
57
+ <group
58
+ name="IRB1200_7_70_IRC5_FLG"
59
+ position={[0, 0.082, 0]}
60
+ />
61
+ <mesh
62
+ name="IRB1200_7_70_IRC5_L06"
63
+ castShadow
64
+ receiveShadow
65
+ geometry={nodes.IRB1200_7_70_IRC5_L06.geometry}
66
+ material={materials["IRB1200_7-70_IRC5.003_Bake"]}
67
+ />
68
+ </animated.group>
69
+ <mesh
70
+ name="IRB1200_7_70_IRC5_L05"
71
+ castShadow
72
+ receiveShadow
73
+ geometry={nodes.IRB1200_7_70_IRC5_L05.geometry}
74
+ material={materials["IRB1200_7-70_IRC5.003_Bake"]}
75
+ />
76
+ </animated.group>
77
+ <mesh
78
+ name="IRB1200_7_70_IRC5_L04"
79
+ castShadow
80
+ receiveShadow
81
+ geometry={nodes.IRB1200_7_70_IRC5_L04.geometry}
82
+ material={materials["IRB1200_7-70_IRC5.003_Bake"]}
83
+ />
84
+ </animated.group>
85
+ <mesh
86
+ name="IRB1200_7_70_IRC5_L03"
87
+ castShadow
88
+ receiveShadow
89
+ geometry={nodes.IRB1200_7_70_IRC5_L03.geometry}
90
+ material={materials["IRB1200_7-70_IRC5.003_Bake"]}
91
+ />
92
+ </animated.group>
93
+ <mesh
94
+ name="IRB1200_7_70_IRC5_L02"
95
+ castShadow
96
+ receiveShadow
97
+ geometry={nodes.IRB1200_7_70_IRC5_L02.geometry}
98
+ material={materials["IRB1200_7-70_IRC5.003_Bake"]}
99
+ />
100
+ </animated.group>
101
+ <mesh
102
+ name="IRB1200_7_70_IRC5_L01"
103
+ castShadow
104
+ receiveShadow
105
+ geometry={nodes.IRB1200_7_70_IRC5_L01.geometry}
106
+ material={materials["IRB1200_7-70_IRC5.003_Bake"]}
107
+ rotation={[Math.PI / 2, 0, 0]}
108
+ />
109
+ </animated.group>
110
+ <mesh
111
+ name="IRB1200_7_70_IRC5_L00"
112
+ castShadow
113
+ receiveShadow
114
+ geometry={nodes.IRB1200_7_70_IRC5_L00.geometry}
115
+ material={materials["IRB1200_7-70_IRC5.003_Bake"]}
116
+ rotation={[-Math.PI / 2, 0, 0]}
117
+ />
118
+ </group>
119
+ </group>
120
+ </group>
121
+ </>
122
+ )
123
+ }
@@ -0,0 +1,3 @@
1
+ export type AxisConfig = number[]
2
+
3
+ export const defaultAxisConfig: AxisConfig = Array(6).fill(2 * Math.PI)
@@ -0,0 +1,129 @@
1
+ import { Vector3, Matrix4, Quaternion } from "three"
2
+ import { Line } from "@react-three/drei"
3
+ import type { LineGeometry } from "three/examples/jsm/lines/LineGeometry.js"
4
+ import type { DHParameter } from "@wandelbots/wandelbots-api-client"
5
+ import RobotAnimator from "./RobotAnimator"
6
+ import type * as THREE from "three"
7
+ import {
8
+ getAllJointsByName,
9
+ type RobotSceneJoint,
10
+ } from "../utils/robotTreeQuery"
11
+ import type { DHRobotProps } from "./SupportedRobot"
12
+
13
+ const CHILD_LINE = "line"
14
+ const CHILD_MESH = "mesh"
15
+
16
+ export function DHRobot({ connectedMotionGroup, ...props }: DHRobotProps) {
17
+ // reused in every update
18
+ const accumulatedMatrix = new Matrix4()
19
+
20
+ // Updates accumulatedMatrix with every execution
21
+ // Reset the matrix to identity if you start a new position update
22
+ function getLinePoints(
23
+ dhParameter: DHParameter,
24
+ jointRotation: number,
25
+ ): {
26
+ a: THREE.Vector3
27
+ b: THREE.Vector3
28
+ } {
29
+ const position = new Vector3()
30
+ const quaternion = new Quaternion()
31
+ const scale = new Vector3()
32
+ accumulatedMatrix.decompose(position, quaternion, scale)
33
+ const prevPosition = position.clone() // Update the previous position
34
+
35
+ const matrix = new Matrix4()
36
+ .makeRotationY(
37
+ dhParameter.theta! +
38
+ jointRotation * (dhParameter.reverse_rotation_direction ? -1 : 1),
39
+ ) // Rotate around Z
40
+ .multiply(new Matrix4().makeTranslation(0, dhParameter.d! / 1000, 0)) // Translate along Z
41
+ .multiply(new Matrix4().makeTranslation(dhParameter.a! / 1000, 0, 0)) // Translate along X
42
+ .multiply(new Matrix4().makeRotationX(dhParameter.alpha!)) // Rotate around X
43
+
44
+ // Accumulate transformations
45
+ accumulatedMatrix.multiply(matrix)
46
+ accumulatedMatrix.decompose(position, quaternion, scale)
47
+ return { a: prevPosition, b: position }
48
+ }
49
+
50
+ function setJointLineRotation(
51
+ jointIndex: number,
52
+ line: THREE.Line,
53
+ mesh: THREE.Mesh,
54
+ jointValue: number,
55
+ ) {
56
+ const dh_parameters =
57
+ connectedMotionGroup.motionGroupSpecification.dh_parameters
58
+ if (!dh_parameters) {
59
+ return
60
+ }
61
+
62
+ const dh_parameter = dh_parameters[jointIndex]
63
+ if (!dh_parameter) {
64
+ return
65
+ }
66
+
67
+ const { a, b } = getLinePoints(dh_parameter, jointValue)
68
+ const lineGeometry = line.geometry as LineGeometry
69
+ lineGeometry.setPositions([a.toArray(), b.toArray()].flat())
70
+
71
+ mesh.position.set(b.x, b.y, b.z)
72
+ }
73
+
74
+ function setRotation(joints: THREE.Object3D[], jointValues: number[]) {
75
+ accumulatedMatrix.identity()
76
+ joints.forEach((joint, jointIndex) => {
77
+ setJointLineRotation(
78
+ jointIndex,
79
+ joint.getObjectByName(CHILD_LINE) as THREE.Line,
80
+ joint.getObjectByName(CHILD_MESH) as THREE.Mesh,
81
+ jointValues[jointIndex]!,
82
+ )
83
+ })
84
+ }
85
+
86
+ function getAllJoints(rootObject: THREE.Object3D): RobotSceneJoint[] {
87
+ return getAllJointsByName(rootObject, "^group_[0-9]+$")
88
+ }
89
+
90
+ return (
91
+ <>
92
+ <RobotAnimator
93
+ connectedMotionGroup={connectedMotionGroup}
94
+ robotRootObjectName="Scene"
95
+ onRotationChanged={setRotation}
96
+ jointCollector={getAllJoints}
97
+ />
98
+ <group {...props} name="Scene">
99
+ <mesh>
100
+ <sphereGeometry args={[0.01, 32, 32]} />
101
+ <meshStandardMaterial color={"black"} depthTest={true} />
102
+ </mesh>
103
+ {connectedMotionGroup.motionGroupSpecification.dh_parameters!.map(
104
+ (param, index) => {
105
+ const { a, b } = getLinePoints(
106
+ param,
107
+ connectedMotionGroup.rapidlyChangingMotionState.state
108
+ .joint_position.joints[index] ?? 0,
109
+ )
110
+ return (
111
+ <group name={`group_${index}`} key={"group_" + index}>
112
+ <Line
113
+ name={CHILD_LINE}
114
+ points={[a, b]}
115
+ color={"white"}
116
+ lineWidth={5}
117
+ />
118
+ <mesh name={CHILD_MESH} key={"mesh_" + index} position={b}>
119
+ <sphereGeometry args={[0.01, 32, 32]} />
120
+ <meshStandardMaterial color={"black"} depthTest={true} />
121
+ </mesh>
122
+ </group>
123
+ )
124
+ },
125
+ )}
126
+ </group>
127
+ </>
128
+ )
129
+ }