motion-master-client 0.0.324 → 0.0.325

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,302 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LimitedRangeSystemIdentification = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const rxjs_1 = require("rxjs");
6
+ const os_command_1 = require("./os-command");
7
+ const cia402_1 = require("./cia402");
8
+ const util_1 = require("./util");
9
+ const device_1 = require("./device");
10
+ /**
11
+ * Formats a number as a hexadecimal string, prefixed with `0x`.
12
+ *
13
+ * @param value - The numeric value to format.
14
+ * @returns The hexadecimal string representation of the value.
15
+ */
16
+ function hex(value) {
17
+ return `0x${value === null || value === void 0 ? void 0 : value.toString(16).toUpperCase()}`;
18
+ }
19
+ /**
20
+ * Performs a limited-range system identification procedure on a device.
21
+ *
22
+ * This class safely executes the system identification process while preserving
23
+ * the device's original configuration (PID parameters, encoder settings, position
24
+ * feedback filter). It emits notifications about progress and status updates, which
25
+ * can be displayed in a UI or logged for debugging.
26
+ */
27
+ class LimitedRangeSystemIdentification {
28
+ /**
29
+ * Creates a new instance of the limited-range system identification routine.
30
+ *
31
+ * @param client - The Motion Master client used for communication with the device.
32
+ * @param deviceRef - A reference to the target device.
33
+ * @param options - Configuration options for the procedure.
34
+ */
35
+ constructor(client, deviceRef, options = {
36
+ hrdStreamingDuration: 4000,
37
+ modesOfOperation: cia402_1.ModesOfOperation.CYCLIC_SYNC_POSITION_MODE,
38
+ rangeLimitEff: 10000,
39
+ rangeLimitMin: 1000,
40
+ signalType: os_command_1.SystemIdentificationOsCommandSignalType.LOGARITHMIC_WITH_AMPLITUDE_MODULATION,
41
+ startFrequency: 1000,
42
+ startProcedure: os_command_1.SystemIdentificationOsCommandStartProcedure.WAIT_FOR_HRD_STREAMING_TO_START,
43
+ targetAmplitude: 300,
44
+ targetFrequency: 100000,
45
+ transitionTime: 3000,
46
+ }) {
47
+ this.client = client;
48
+ this.deviceRef = deviceRef;
49
+ this.options = options;
50
+ /**
51
+ * Emits status and progress messages during the procedure.
52
+ * Subscribers can display these messages in a UI or log them.
53
+ */
54
+ this.notifications$ = new rxjs_1.Subject();
55
+ /**
56
+ * Indicates whether the system identification procedure is currently running.
57
+ */
58
+ this.isRunning = false;
59
+ }
60
+ /**
61
+ * Starts the limited-range system identification procedure.
62
+ *
63
+ * This method:
64
+ * - Ensures the device is in a safe state.
65
+ * - Computes and sets initial PID values.
66
+ * - Starts data monitoring for position feedback.
67
+ * - Runs the chirp signal on the device.
68
+ * - Computes the plant model without the chirp signal.
69
+ * - Restores all device settings to their original values.
70
+ *
71
+ * Emits notifications to `notifications$` for each major step and error.
72
+ *
73
+ * @throws Will throw an error if any of the device requests fail.
74
+ */
75
+ start() {
76
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
77
+ // Small delay to ensure subscribers to notifications$ are ready
78
+ yield (0, util_1.resolveAfter)(1);
79
+ // Prevent concurrent executions of the procedure
80
+ if (this.isRunning) {
81
+ this.notifications$.next('Limited Range System Identification is already running.');
82
+ return;
83
+ }
84
+ // Mark the procedure as running
85
+ this.isRunning = true;
86
+ // Validate and adjust HRD streaming duration if necessary
87
+ if (this.options.hrdStreamingDuration < this.options.transitionTime) {
88
+ this.notifications$.next(`Warning: hrdStreamingDuration (${this.options.hrdStreamingDuration} ms) is shorter than transitionTime (${this.options.transitionTime} ms). Increasing hrdStreamingDuration by 1 second to ensure proper timing.`);
89
+ this.options.hrdStreamingDuration = this.options.transitionTime + 1000; // 1-second buffer
90
+ }
91
+ // Ensure the required Modes of Operation is set
92
+ if (this.options.modesOfOperation !== cia402_1.ModesOfOperation.CYCLIC_SYNC_POSITION_MODE) {
93
+ this.notifications$.next(`Warning: modesOfOperation is set to ${this.options.modesOfOperation}, but CYCLIC_SYNC_POSITION_MODE (8) is required for this procedure. Applying the required mode automatically.`);
94
+ this.options.modesOfOperation = cia402_1.ModesOfOperation.CYCLIC_SYNC_POSITION_MODE;
95
+ }
96
+ // Ensure the required Start Procedure is set
97
+ if (this.options.startProcedure !== os_command_1.SystemIdentificationOsCommandStartProcedure.WAIT_FOR_HRD_STREAMING_TO_START) {
98
+ this.notifications$.next(`Warning: startProcedure is currently ${this.options.startProcedure}, but WAIT_FOR_HRD_STREAMING_TO_START (2) is required. Setting the correct start procedure automatically.`);
99
+ this.options.startProcedure = os_command_1.SystemIdentificationOsCommandStartProcedure.WAIT_FOR_HRD_STREAMING_TO_START;
100
+ }
101
+ // Variables to hold original configurations for restoration later
102
+ let encCom;
103
+ let encPos;
104
+ const dataMonitoring = this.client.createDataMonitoring([[this.deviceRef, 0x6064, 0x00]], 50000); // 50 ms interval
105
+ let positionFeedbackFilterType;
106
+ let pKp;
107
+ let pKi;
108
+ let pKd;
109
+ let pCtrlStrategy;
110
+ try {
111
+ // Ensure the drive is in the "Switch On Disabled" state before any motion commands
112
+ this.notifications$.next('Transitioning to "Switch On Disabled" state...');
113
+ yield this.client.request.transitionToCia402State(this.deviceRef, cia402_1.Cia402State.SWITCH_ON_DISABLED);
114
+ this.notifications$.next('"Switch On Disabled" state reached.');
115
+ // Compute the feed constant required for motion control
116
+ this.notifications$.next('Computing feed constant...');
117
+ const feedConstant = yield (0, rxjs_1.lastValueFrom)(this.client.request.computeFeedConstant(this.deviceRef));
118
+ this.notifications$.next(`Feed constant computed: ${feedConstant}`);
119
+ // Disable the position feedback filter
120
+ this.notifications$.next('Disabling the position feedback filter...');
121
+ positionFeedbackFilterType = yield this.client.request.upload(this.deviceRef, 0x2022, 0x01);
122
+ yield this.client.request.download(this.deviceRef, 0x2022, 0x01, 0);
123
+ this.notifications$.next('Position feedback filter disabled.');
124
+ // Retrieve encoder ordinal values for commutation (ENC_COM) and position (ENC_POS) configurations
125
+ this.notifications$.next('Retrieving encoder configurations...');
126
+ encCom = yield this.client.request.upload(this.deviceRef, 0x2010, 0x0c);
127
+ encPos = yield this.client.request.upload(this.deviceRef, 0x2012, 0x09);
128
+ this.notifications$.next(`Encoder configurations retrieved: ENC_COM = ${encCom}, ENC_POS = ${encPos}`);
129
+ // If ENC_COM and ENC_POS do not match, update ENC_POS to match ENC_COM
130
+ if (encCom !== encPos) {
131
+ this.notifications$.next('Encoder configurations do not match. Updating ENC_POS to match ENC_COM...');
132
+ yield this.client.request.download(this.deviceRef, 0x2012, 0x09, encCom);
133
+ this.notifications$.next('ENC_POS updated to match ENC_COM.');
134
+ }
135
+ // Retrieve the encoder resolution based on the ENC_COM configuration
136
+ const encConfigObjIdx = encCom === 1 ? 0x2110 : 0x2112;
137
+ this.notifications$.next(`Getting the encoder resolution from ${hex(encConfigObjIdx)}...`);
138
+ const resolution = yield this.client.request.upload(this.deviceRef, encConfigObjIdx, 0x03);
139
+ this.notifications$.next(`Encoder resolution: ${resolution}`);
140
+ // Calculate adjusted limit range min based on feed constant and encoder resolution
141
+ this.notifications$.next('Calculating limit range based on feed constant and resolution...');
142
+ const rangeLimitEff = this.options.rangeLimitEff;
143
+ // feed constant is not disabled and greater than resolution
144
+ const ratio = feedConstant !== 0xffffffff && feedConstant > resolution ? feedConstant / resolution : 1;
145
+ const rangeLimitMin = Math.round(this.options.rangeLimitMin * ratio);
146
+ this.notifications$.next(`Adjusted range limit: min=${rangeLimitMin}, eff=${rangeLimitEff}`);
147
+ // Retrieve the PID controller parameters
148
+ this.notifications$.next('Retrieving the PID values...');
149
+ [pKp, pKi, pKd, pCtrlStrategy] = (yield this.client.request.uploadMany([
150
+ [this.deviceRef, 0x2012, 0x01],
151
+ [this.deviceRef, 0x2012, 0x02],
152
+ [this.deviceRef, 0x2012, 0x03],
153
+ [this.deviceRef, 0x2002, 0x00],
154
+ ]));
155
+ this.notifications$.next(`PID values retrieved: Kp=${pKp}, Ki=${pKi}, Kd=${pKd}, CtrlStrategy=${pCtrlStrategy}`);
156
+ // Retrieve the maximum torque value from the drive
157
+ this.notifications$.next('Retrieving the maximum torque value...');
158
+ const maxTorque = yield this.client.request.upload(this.deviceRef, 0x6072, 0x00);
159
+ this.notifications$.next(`Maximum torque value retrieved: ${maxTorque}`);
160
+ // Compute the initial kp value and xi squared based on the retrieved parameters
161
+ this.notifications$.next('Computing the initial kp value and xi squared...');
162
+ let kpInit;
163
+ let xiSquared;
164
+ if (feedConstant === 0xffffffff) {
165
+ xiSquared = Math.min(maxTorque, 1000 * Math.sqrt(rangeLimitEff / rangeLimitMin)) * rangeLimitEff;
166
+ kpInit = xiSquared / Math.pow(rangeLimitEff, 2);
167
+ }
168
+ else {
169
+ xiSquared =
170
+ ((Math.min(maxTorque, 1000 * Math.sqrt(rangeLimitEff / rangeLimitMin)) * rangeLimitEff) / feedConstant) *
171
+ resolution;
172
+ kpInit = xiSquared / Math.pow((rangeLimitEff / feedConstant) * resolution, 2);
173
+ }
174
+ this.notifications$.next(`Initial kp value: ${kpInit}, xi squared: ${xiSquared}`);
175
+ // Set the initial PID controller parameters for the procedure
176
+ this.notifications$.next('Setting initial PID values...');
177
+ yield this.client.request.downloadMany([
178
+ [this.deviceRef, 0x2012, 1, kpInit],
179
+ [this.deviceRef, 0x2012, 2, 0],
180
+ [this.deviceRef, 0x2012, 3, 0],
181
+ [this.deviceRef, 0x2002, 0, 1],
182
+ ]);
183
+ this.notifications$.next('Initial PID values set.');
184
+ // Force an on-demand parameters update to apply all settings
185
+ this.notifications$.next('Forcing on-demand parameters update...');
186
+ yield this.client.request.forceOnDemandParametersUpdate(this.deviceRef);
187
+ this.notifications$.next('On-demand parameters update forced.');
188
+ // Start data monitoring for position actual value (0x6064:00) and update Kp based on position error
189
+ this.notifications$.next('Starting data monitoring for position actual value...');
190
+ const posRef = yield this.client.request.upload(this.deviceRef, 0x6064, 0x00);
191
+ dataMonitoring
192
+ .start()
193
+ .pipe(
194
+ // Convert each emitted actual position into a download request to update the position loop Kp,
195
+ // ignoring new emissions until the previous request completes
196
+ (0, rxjs_1.exhaustMap)((data) => {
197
+ const posAct = data[0];
198
+ const e = posRef - posAct;
199
+ let kp;
200
+ if (feedConstant === 0xffffffff) {
201
+ kp = xiSquared / Math.pow(Math.max(rangeLimitEff - Math.abs(e), 1), 2);
202
+ }
203
+ else {
204
+ kp = xiSquared / Math.pow((Math.max(rangeLimitEff - Math.abs(e), 1) / feedConstant) * resolution, 2);
205
+ }
206
+ return (0, rxjs_1.from)(this.client.request.download(this.deviceRef, 0x2012, 0x01, kp));
207
+ }))
208
+ .subscribe();
209
+ this.notifications$.next('Data monitoring started.');
210
+ // Read the current position and set it as the target position to prevent sudden movement
211
+ this.notifications$.next('Setting current position as target position...');
212
+ const positionActualValue = yield this.client.request.upload(this.deviceRef, 0x6064, 0x00);
213
+ yield this.client.request.download(this.deviceRef, 0x607a, 0x00, positionActualValue);
214
+ this.notifications$.next(`Target position set to ${positionActualValue}.`);
215
+ // Run the chirp signal on the device
216
+ this.notifications$.next('Running the chirp signal...');
217
+ yield (0, rxjs_1.lastValueFrom)(this.client.request.runChirpSignal(this.deviceRef, this.options));
218
+ this.notifications$.next('Chirp signal procedure completed.');
219
+ // Stop data monitoring
220
+ this.notifications$.next('Stopping data monitoring...');
221
+ dataMonitoring.stop();
222
+ this.notifications$.next('Data monitoring stopped.');
223
+ // Start the system identification procedure without the chirp signal in order to only compute the plant model
224
+ this.notifications$.next('Starting system identification procedure on Motion Master to compute plant model...');
225
+ const deviceRefObj = (0, device_1.makeDeviceRefObj)(this.deviceRef);
226
+ const props = Object.assign(Object.assign({}, deviceRefObj), { skipChirpSignal: true, nextGenSysId: true, durationSeconds: this.options.transitionTime / 1000, endFrequency: this.options.targetFrequency / 1000, startFrequency: this.options.startFrequency / 1000, torqueAmplitude: this.options.targetAmplitude });
227
+ yield (0, rxjs_1.lastValueFrom)(this.client.request.startSystemIdentification(props, 10000));
228
+ this.notifications$.next('Computing plant model completed.');
229
+ }
230
+ catch (error) {
231
+ this.notifications$.next(`Error during procedure: ${error instanceof Error ? error.message : error}`);
232
+ throw error;
233
+ }
234
+ finally {
235
+ // Mark the procedure as not running
236
+ this.isRunning = false;
237
+ // Stop data monitoring
238
+ this.notifications$.next('Stopping data monitoring...');
239
+ dataMonitoring.stop();
240
+ this.notifications$.next('Data monitoring stopped.');
241
+ // Ensure the drive is in the "Switch On Disabled" after the procedure
242
+ this.notifications$.next('Transitioning to "Switch On Disabled" state...');
243
+ try {
244
+ yield this.client.request.transitionToCia402State(this.deviceRef, cia402_1.Cia402State.SWITCH_ON_DISABLED);
245
+ this.notifications$.next('"Switch On Disabled" state reached.');
246
+ }
247
+ catch (err) {
248
+ this.notifications$.next(`Failed to transition to "Switch On Disabled": ${err instanceof Error ? err.message : err}`);
249
+ }
250
+ // Restore original ENC_POS configuration if it was changed
251
+ if (encCom !== undefined && encPos !== undefined && encCom !== encPos) {
252
+ this.notifications$.next(`Restoring original ENC_POS configuration ${encPos}...`);
253
+ try {
254
+ yield this.client.request.download(this.deviceRef, 0x2012, 0x09, encPos);
255
+ this.notifications$.next('ENC_POS configuration restored.');
256
+ }
257
+ catch (err) {
258
+ this.notifications$.next(`Failed to restore ENC_POS: ${err instanceof Error ? err.message : err}`);
259
+ }
260
+ }
261
+ // Restore the position feedback filter if it was changed
262
+ if (positionFeedbackFilterType !== undefined && positionFeedbackFilterType !== 0) {
263
+ this.notifications$.next('Restoring the position feedback filter...');
264
+ try {
265
+ yield this.client.request.download(this.deviceRef, 0x2022, 0x01, positionFeedbackFilterType);
266
+ this.notifications$.next('Position feedback filter restored.');
267
+ }
268
+ catch (err) {
269
+ this.notifications$.next(`Failed to restore position feedback filter: ${err instanceof Error ? err.message : err}`);
270
+ }
271
+ }
272
+ // Restore the original PID controller parameters
273
+ if (pKp !== undefined && pKi !== undefined && pKd !== undefined && pCtrlStrategy !== undefined) {
274
+ this.notifications$.next('Restoring original PID values...');
275
+ try {
276
+ yield this.client.request.downloadMany([
277
+ [this.deviceRef, 0x2012, 0x01, pKp],
278
+ [this.deviceRef, 0x2012, 0x02, pKi],
279
+ [this.deviceRef, 0x2012, 0x03, pKd],
280
+ [this.deviceRef, 0x2002, 0x00, pCtrlStrategy],
281
+ ]);
282
+ this.notifications$.next('Original PID values restored.');
283
+ }
284
+ catch (err) {
285
+ this.notifications$.next(`Failed to restore PID values: ${err instanceof Error ? err.message : err}`);
286
+ }
287
+ }
288
+ // Force an on-demand parameters update to apply all restored settings
289
+ this.notifications$.next('Forcing on-demand parameters update...');
290
+ try {
291
+ yield this.client.request.forceOnDemandParametersUpdate(this.deviceRef);
292
+ this.notifications$.next('On-demand parameters update forced.');
293
+ }
294
+ catch (err) {
295
+ this.notifications$.next(`Failed to force on-demand parameters update: ${err instanceof Error ? err.message : err}`);
296
+ }
297
+ }
298
+ });
299
+ }
300
+ }
301
+ exports.LimitedRangeSystemIdentification = LimitedRangeSystemIdentification;
302
+ //# sourceMappingURL=limited-range-system-identification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limited-range-system-identification.js","sourceRoot":"","sources":["../../../../../libs/motion-master-client/src/lib/limited-range-system-identification.ts"],"names":[],"mappings":"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"}
@@ -1258,9 +1258,29 @@ export declare class MotionMasterReqResClient {
1258
1258
  */
1259
1259
  factoryReset(deviceRef: DeviceRef, filesToKeep?: string[], installEmptyFirmware?: boolean, reloadFirmware?: boolean): Observable<RequestStatusMessage>;
1260
1260
  /**
1261
- * Computes the Feed Constant as the quotient of Feed (0x6092:01) and Shaft Revolutions (0x6092:02).
1261
+ * Computes the Feed Constant for a given device.
1262
+ *
1263
+ * The Feed Constant is calculated as the quotient of:
1264
+ * - `0x6092:01`: Feed
1265
+ * - `0x6092:02`: Shaft Revolutions
1266
+ *
1267
+ * @param deviceRef - Reference to the device for which the Feed Constant is computed.
1268
+ * @param requestTimeout - Optional timeout in milliseconds for the parameter request (default: 5000).
1269
+ * @returns An Observable that emits the computed Feed Constant as a number.
1262
1270
  */
1263
1271
  computeFeedConstant(deviceRef: DeviceRef, requestTimeout?: number): Observable<number>;
1272
+ /**
1273
+ * Computes the Gear Ratio for a given device.
1274
+ *
1275
+ * The Gear Ratio is calculated as the quotient of:
1276
+ * - Gear Ratio Numerator (`0x6091:01` – Motor Revolutions)
1277
+ * - Gear Ratio Denominator (`0x6091:02` – Shaft Revolutions)
1278
+ *
1279
+ * @param deviceRef - Reference to the device for which the Gear Ratio is computed.
1280
+ * @param requestTimeout - Optional timeout in milliseconds for the parameter request (default: 5000).
1281
+ * @returns An Observable that emits the computed Gear Ratio as a number.
1282
+ */
1283
+ computeGearRatio(deviceRef: DeviceRef, requestTimeout?: number): Observable<number>;
1264
1284
  /**
1265
1285
  * Save the modified parameter values to the config.csv file so that they are used the next time the device is power cycled.
1266
1286
  * The configuration is saved using the 0x1010: Store parameters object.
@@ -2099,4 +2119,22 @@ export declare class MotionMasterReqResClient {
2099
2119
  * will also be executed.
2100
2120
  */
2101
2121
  runChirpSignal(deviceRef: DeviceRef, options: ChirpSignalOptions): Observable<number[][]>;
2122
+ /**
2123
+ * Reads the motor and shaft revolutions from a device and calculates the gear ratio.
2124
+ *
2125
+ * The gear ratio is defined as the number of motor revolutions per one shaft revolution:
2126
+ *
2127
+ * gearRatio = motorRev / shaftRev
2128
+ *
2129
+ * If either motorRev or shaftRev is zero or negative, the function returns a default value of 1.
2130
+ *
2131
+ * @param deviceRef - Reference to the device from which to read the values.
2132
+ * @returns A Promise that resolves to the gear ratio (positive number). Returns 1 if the readings are invalid.
2133
+ *
2134
+ * @remarks
2135
+ * - Both motorRev and shaftRev are read via `upload()` from the device object dictionary at index 0x6091.
2136
+ * - Ensure that `upload()` returns numeric values and not raw buffers.
2137
+ * - This function assumes positive values; a negative value may indicate an error or reversed rotation.
2138
+ */
2139
+ getGearRatio(deviceRef: DeviceRef): Promise<number>;
2102
2140
  }
@@ -1863,6 +1863,7 @@ class MotionMasterReqResClient {
1863
1863
  if (content) {
1864
1864
  try {
1865
1865
  const buffer = buffer_1.Buffer.from(content);
1866
+ // @ts-ignore
1866
1867
  const text = (0, util_1.decodeTextContent)(buffer);
1867
1868
  return JSON.parse(text);
1868
1869
  }
@@ -2521,7 +2522,15 @@ class MotionMasterReqResClient {
2521
2522
  }));
2522
2523
  }
2523
2524
  /**
2524
- * Computes the Feed Constant as the quotient of Feed (0x6092:01) and Shaft Revolutions (0x6092:02).
2525
+ * Computes the Feed Constant for a given device.
2526
+ *
2527
+ * The Feed Constant is calculated as the quotient of:
2528
+ * - `0x6092:01`: Feed
2529
+ * - `0x6092:02`: Shaft Revolutions
2530
+ *
2531
+ * @param deviceRef - Reference to the device for which the Feed Constant is computed.
2532
+ * @param requestTimeout - Optional timeout in milliseconds for the parameter request (default: 5000).
2533
+ * @returns An Observable that emits the computed Feed Constant as a number.
2525
2534
  */
2526
2535
  computeFeedConstant(deviceRef, requestTimeout = 5000) {
2527
2536
  return this.getParameterValues([
@@ -2529,6 +2538,23 @@ class MotionMasterReqResClient {
2529
2538
  [deviceRef, 0x6092, 2], // Shaft revolutions
2530
2539
  ], false, requestTimeout).pipe((0, operators_1.map)((values) => values[0] / values[1]));
2531
2540
  }
2541
+ /**
2542
+ * Computes the Gear Ratio for a given device.
2543
+ *
2544
+ * The Gear Ratio is calculated as the quotient of:
2545
+ * - Gear Ratio Numerator (`0x6091:01` – Motor Revolutions)
2546
+ * - Gear Ratio Denominator (`0x6091:02` – Shaft Revolutions)
2547
+ *
2548
+ * @param deviceRef - Reference to the device for which the Gear Ratio is computed.
2549
+ * @param requestTimeout - Optional timeout in milliseconds for the parameter request (default: 5000).
2550
+ * @returns An Observable that emits the computed Gear Ratio as a number.
2551
+ */
2552
+ computeGearRatio(deviceRef, requestTimeout = 5000) {
2553
+ return this.getParameterValues([
2554
+ [deviceRef, 0x6091, 1],
2555
+ [deviceRef, 0x6091, 2], // Gear Ratio Denominator (`0x6091:02` – Shaft Revolutions)
2556
+ ], false, requestTimeout).pipe((0, operators_1.map)((values) => values[0] / values[1]));
2557
+ }
2532
2558
  /**
2533
2559
  * Save the modified parameter values to the config.csv file so that they are used the next time the device is power cycled.
2534
2560
  * The configuration is saved using the 0x1010: Store parameters object.
@@ -2981,6 +3007,7 @@ class MotionMasterReqResClient {
2981
3007
  loginToSmmForParameterDownload(deviceRef, username, password, commandTimeout = 5000, responsePollingInterval = 500) {
2982
3008
  const command = (0, os_command_1.createSmmAcyclicHandlerOsCommand)(os_command_1.SmmAcyclicHandlerSubcommandId.PARAMETER_DOWNLOAD_LOGIN);
2983
3009
  const content = (0, smm_1.packSmmCredentials)(username, password);
3010
+ // @ts-ignore
2984
3011
  return this.runOsCommandAndWriteFsBuffer(deviceRef, command, content, commandTimeout, responsePollingInterval).pipe((0, operators_1.last)(), (0, operators_1.map)((response) => {
2985
3012
  if (response.request !== 'succeeded') {
2986
3013
  throw new Error('Login to SMM for parameter download failed.');
@@ -3008,6 +3035,7 @@ class MotionMasterReqResClient {
3008
3035
  loginToSmmForSoftwareUpdate(deviceRef, username, password, commandTimeout = 10000, responsePollingInterval = 500) {
3009
3036
  const command = (0, os_command_1.createSmmAcyclicHandlerOsCommand)(os_command_1.SmmAcyclicHandlerSubcommandId.SOFTWARE_UPDATE_LOGIN);
3010
3037
  const content = (0, smm_1.packSmmCredentials)(username, password);
3038
+ // @ts-ignore
3011
3039
  return this.runOsCommandAndWriteFsBuffer(deviceRef, command, content, commandTimeout, responsePollingInterval).pipe((0, operators_1.last)(), (0, operators_1.map)((response) => {
3012
3040
  if (response.request !== 'succeeded') {
3013
3041
  throw new Error('Login to SMM for software update failed.');
@@ -3072,6 +3100,7 @@ class MotionMasterReqResClient {
3072
3100
  changeSmmPassword(deviceRef, oldPassword, newPassword, commandTimeout = 10000, responsePollingInterval = 500) {
3073
3101
  const command = (0, os_command_1.createSmmAcyclicHandlerOsCommand)(os_command_1.SmmAcyclicHandlerSubcommandId.CHANGE_PASSWORD);
3074
3102
  const content = (0, smm_1.packSmmChangePassword)(newPassword, oldPassword);
3103
+ // @ts-ignore
3075
3104
  return this.runOsCommandAndWriteFsBuffer(deviceRef, command, content, commandTimeout, responsePollingInterval).pipe((0, operators_1.last)(), (0, operators_1.mergeMap)(() => this.triggerSmmRestart(deviceRef)));
3076
3105
  }
3077
3106
  /**
@@ -3194,7 +3223,9 @@ class MotionMasterReqResClient {
3194
3223
  const packedCrc = (0, smm_1.packSmmSoftwareUpdateCrc)(crc);
3195
3224
  const finalizeSoftwareUpdateCommand = (0, os_command_1.createSmmAcyclicHandlerOsCommand)(os_command_1.SmmAcyclicHandlerSubcommandId.FINALIZE_SOFTWARE_UPDATE);
3196
3225
  // Step 6: Send the CRC to validate data integrity.
3197
- observables.push((0, rxjs_1.defer)(() => this.runOsCommandAndWriteFsBuffer(deviceRef, finalizeSoftwareUpdateCommand, packedCrc).pipe((0, operators_1.last)(), (0, operators_1.map)((response) => {
3226
+ observables.push((0, rxjs_1.defer)(() =>
3227
+ // @ts-ignore
3228
+ this.runOsCommandAndWriteFsBuffer(deviceRef, finalizeSoftwareUpdateCommand, packedCrc).pipe((0, operators_1.last)(), (0, operators_1.map)((response) => {
3198
3229
  if (response.request !== 'succeeded') {
3199
3230
  throw new Error('Finalizing SMM software update failed.');
3200
3231
  }
@@ -3226,7 +3257,9 @@ class MotionMasterReqResClient {
3226
3257
  return (parameterStructureVersion ? (0, rxjs_1.of)(parameterStructureVersion) : this.resolveSmmParameterStructureVersion(deviceRef)).pipe((0, operators_1.mergeMap)((version) => {
3227
3258
  const command = (0, os_command_1.createSmmAcyclicHandlerOsCommand)(os_command_1.SmmAcyclicHandlerSubcommandId.TRANSMIT_PARAMETERS);
3228
3259
  const { buffer: content } = (0, smm_1.packSmmParameterValues)(values, version);
3229
- return this.runOsCommandAndWriteFsBuffer(deviceRef, command, content, commandTimeout, responsePollingInterval).pipe((0, operators_1.last)(), (0, operators_1.map)((response) => {
3260
+ return this.runOsCommandAndWriteFsBuffer(deviceRef, command,
3261
+ // @ts-ignore
3262
+ content, commandTimeout, responsePollingInterval).pipe((0, operators_1.last)(), (0, operators_1.map)((response) => {
3230
3263
  if (response.request !== 'succeeded') {
3231
3264
  throw new Error('Transmitting SMM parameters failed.');
3232
3265
  }
@@ -3727,6 +3760,7 @@ class MotionMasterReqResClient {
3727
3760
  }));
3728
3761
  }));
3729
3762
  }
3763
+ // TODO: Move to another file
3730
3764
  getMaxValuePercentageColor(percentage) {
3731
3765
  if (percentage >= 50 && percentage <= 100) {
3732
3766
  return '#6ba853';
@@ -3742,6 +3776,7 @@ class MotionMasterReqResClient {
3742
3776
  }
3743
3777
  return '';
3744
3778
  }
3779
+ // TODO: Move to another file
3745
3780
  getMaxValuePercentageLabel(percentage) {
3746
3781
  if (percentage >= 50 && percentage <= 100) {
3747
3782
  return 'Calibration was successful. Encoder system is robust to mechanical displacements and temperature expansions.';
@@ -4131,6 +4166,35 @@ class MotionMasterReqResClient {
4131
4166
  }
4132
4167
  }));
4133
4168
  }
4169
+ /**
4170
+ * Reads the motor and shaft revolutions from a device and calculates the gear ratio.
4171
+ *
4172
+ * The gear ratio is defined as the number of motor revolutions per one shaft revolution:
4173
+ *
4174
+ * gearRatio = motorRev / shaftRev
4175
+ *
4176
+ * If either motorRev or shaftRev is zero or negative, the function returns a default value of 1.
4177
+ *
4178
+ * @param deviceRef - Reference to the device from which to read the values.
4179
+ * @returns A Promise that resolves to the gear ratio (positive number). Returns 1 if the readings are invalid.
4180
+ *
4181
+ * @remarks
4182
+ * - Both motorRev and shaftRev are read via `upload()` from the device object dictionary at index 0x6091.
4183
+ * - Ensure that `upload()` returns numeric values and not raw buffers.
4184
+ * - This function assumes positive values; a negative value may indicate an error or reversed rotation.
4185
+ */
4186
+ getGearRatio(deviceRef) {
4187
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
4188
+ const motorRev = yield this.upload(deviceRef, 0x6091, 1);
4189
+ const shaftRev = yield this.upload(deviceRef, 0x6091, 2);
4190
+ if (motorRev > 0 && shaftRev > 0) {
4191
+ return motorRev / shaftRev;
4192
+ }
4193
+ else {
4194
+ return 1;
4195
+ }
4196
+ });
4197
+ }
4134
4198
  }
4135
4199
  exports.MotionMasterReqResClient = MotionMasterReqResClient;
4136
4200
  /**