"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntegroEncoderCalibration = exports.parseIntegroEncoderFirmwareVersion = void 0;
const tslib_1 = require("tslib");
const rxjs_1 = require("rxjs");
const units_1 = require("./units");
const cia402_1 = require("./cia402");
const os_command_1 = require("./os-command");
const util_1 = require("./util");
const product_1 = require("./product");
const parameter_1 = require("./parameter");
function hex(value) {
    return `0x${value === null || value === void 0 ? void 0 : value.toString(16).toUpperCase()}`;
}
function parseIntegroEncoderFirmwareVersion(value) {
    const str = String(value).padStart(10, '0');
    const major = str.slice(0, 2);
    const minor = str.slice(2, 4);
    const datestamp = str.slice(4);
    const year = datestamp.slice(0, 2);
    const month = datestamp.slice(2, 4);
    const day = datestamp.slice(4, 6);
    return { value, major, minor, datestamp, year, month, day };
}
exports.parseIntegroEncoderFirmwareVersion = parseIntegroEncoderFirmwareVersion;
class IntegroEncoderCalibration {
    constructor(client, deviceRef) {
        this.client = client;
        this.deviceRef = deviceRef;
        this.notifications$ = new rxjs_1.Subject();
        this.originalVelocityWindow = 0; // 0x606D:00
        this.originalVelocityWindowTime = 0; // 0x606E:00
        this.maxMotorSpeed = 0;
        this.originalMaxMotorSpeed = 0; // 0x6080:00
        this.quickStopDeceleration = 0;
        this.originalQuickStopDeceleration = 0; // 0x6085:00
        this.feedConstantFeed = 0;
        this.originalFeedConstantFeed = 0; // 0x6092:01
        this.feedConstantShaftRevolutions = 0;
        this.originalFeedConstantShaftRevolutions = 0; // 0x6092:02
        this.feedConstant = 0;
        this.originalFeedConstant = 0; // feed / shaft revolutions
        this.siUnitVelocity = 0;
        this.originalSiUnitVelocity = 0; // 0x60A9:00
        this.ccwVelocityProfile = {
            target: 3000,
            acceleration: 6000,
            deceleration: 6000, // RPM/s
        };
        this.cwVelocityProfile = {
            target: -3000,
            acceleration: 6000,
            deceleration: 6000, // RPM/s
        };
    }
    start(debug = false) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            // This is a workaround for cases where the response from the previous OS command was not read, causing the next OS command to fail until the response is properly processed.
            // Failing to read the response after running an OS command, before the command succeeds or fails, is a bug in the OS command handling implementation, likely in Motion Master.
            try {
                const response = yield (0, rxjs_1.lastValueFrom)(this.client.request.readOsCommandResponse(this.deviceRef));
                if (response.request === 'started' || response.request === 'running') {
                    this.notifications$.next(`The OS command response is still being processed: ${response.request}. Aborting the calibration procedure.`);
                    return;
                }
            }
            catch (err) {
                if (err instanceof Error) {
                    this.notifications$.next(`Error reading the OS command response at the beginning: ${err.message}. Continuing with the calibration procedure.`);
                }
            }
            // The calibration procedure should be performed after the drive is fully commissioned, and thus, the drive should be fully operational in Velocity mode.
            // Tuning of the control loop should be done by the user.
            this.notifications$.next(`Validating the device (${this.deviceRef}) before starting the encoder calibration.`);
            yield this.validateDevice();
            yield this.updateVelocityParameterValues();
            // Retrieve the encoder firmware version and display it.
            let osCommandResponse = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0, 0x04, 4, 0, 10000, 1000, false));
            const encoderFirmwareVersion = parseIntegroEncoderFirmwareVersion(osCommandResponse.kublerRegisterValue);
            this.notifications$.next(`The firmware version of the integrated encoder (register 0x04) is: Major=${encoderFirmwareVersion.major}, Minor=${encoderFirmwareVersion.minor}, Date=${encoderFirmwareVersion.datestamp}, Value=${encoderFirmwareVersion.value}.`);
            try {
                yield this.client.request.resetFault(this.deviceRef);
            }
            catch (_a) { } // ignore
            // Retrieve the encoder configuration index assigned to Port 1.
            const encoder1ConfigurationSensorPort = yield this.client.request.upload(this.deviceRef, 0x2110, 1);
            const encoderConfigurationIndex = encoder1ConfigurationSensorPort === 1 ? 0x2110 : 0x2112;
            this.notifications$.next(`Setting the integrated encoder sampling frequency to 16 kHz (${hex(encoderConfigurationIndex)}:28 = 1).`);
            yield this.client.request.download(this.deviceRef, encoderConfigurationIndex, 28, 1);
            yield (0, util_1.resolveAfter)(200);
            yield this.client.request.forceOnDemandParametersUpdate(this.deviceRef);
            this.notifications$.next('Switching the source of the velocity to the value provided by the encoder.');
            yield (0, rxjs_1.lastValueFrom)(this.client.request.runUseInternalEncoderVelocityOsCommand(this.deviceRef, 1, 10000, 1000, false));
            yield (0, util_1.resolveAfter)(200);
            // Convert the POE calibration velocity profile values and update the device.
            let velocityProfile = yield this.setVelocityProfile(this.ccwVelocityProfile, 2);
            this.notifications$.next('Setting modes of operation to Profile velocity mode and transitioning to Operation enabled CiA402 state.');
            yield (0, rxjs_1.lastValueFrom)(this.client.request.setModesOfOperation(this.deviceRef, cia402_1.ModesOfOperation.PROFILE_VELOCITY_MODE));
            yield this.client.request.transitionToCia402State(this.deviceRef, cia402_1.Cia402State.OPERATION_ENABLED);
            try {
                yield this.client.whenTargetReached(this.deviceRef, 500, 5000);
                yield this.notifyParameterValue(0x606c, 0); // Velocity actual value
                // Trigger the POA automatic calibration with an OS command.
                this.notifications$.next('Triggering automatic calibration of the POA by setting register 0x25 to 0x09.');
                yield this.writeEncoderRegisterValueAndValidateResponse(0x25, 0x09);
                yield (0, util_1.resolveAfter)(500);
            }
            catch (_err) {
                this.client.request.quickStop(this.deviceRef).catch();
                this.notifications$.next(`Target velocity ${velocityProfile.target} can't be reached. Aborting the calibration procedure.`);
                this.revertVelocityParameterValues();
                return;
            }
            this.notifications$.next('Polling the encoder register 0x24 until its value equals 0x11 or until 8 seconds have passed.');
            // Read the value of the encoder register 0x24 until its value equals 0x11 or until 8 seconds have passed.
            osCommandResponse = yield (0, rxjs_1.lastValueFrom)((0, rxjs_1.defer)(() => this.client.request
                .runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0, 0x24, 1, 0, 10000, 1000, false)
                .pipe((0, rxjs_1.repeat)({ count: 16, delay: 500 }), (0, rxjs_1.takeWhile)((osCommandResponse) => {
                if (debug) {
                    this.notifications$.next(`Value read from the encoder register 0x24 is ${hex(osCommandResponse.kublerRegisterValue)}.`);
                }
                return (osCommandResponse === null || osCommandResponse === void 0 ? void 0 : osCommandResponse.kublerRegisterValue) !== 0x11;
            }, true))));
            if (osCommandResponse.request === 'failed') {
                this.notifications$.next(`Reading the value of register 0x24 failed. ${osCommandResponse.errorName} (${osCommandResponse.errorCode}): ${osCommandResponse.errorDescription}`);
            }
            else if (osCommandResponse.request === 'succeeded') {
                this.notifications$.next(`The last value retrieved from register 0x24 is ${osCommandResponse.kublerRegisterValue}: ${os_command_1.kublerEncoderRegisterValueMeaning[0x24][osCommandResponse.kublerRegisterValue]}`);
            }
            if (osCommandResponse.kublerRegisterValue !== 0x11) {
                this.client.request.quickStop(this.deviceRef).catch();
                this.notifications$.next('The analogue gains calibration did not converge. Please repeat the procedure.');
                this.revertVelocityParameterValues();
                return;
            }
            yield (0, util_1.resolveAfter)(500);
            // Lookup table learning.
            this.notifications$.next('Running the motor at a constant speed in one direction.');
            // Run the motor at constant speed in one direction.
            try {
                yield this.client.whenTargetReached(this.deviceRef, 500, 5000);
                yield this.notifyParameterValue(0x606c, 0); // Velocity actual value
                this.notifications$.next('Writing 0x00C2 to the encoder register 0x50.');
                yield this.writeEncoderRegisterValueAndValidateResponse(0x50, 0x00c2, 2);
                yield (0, util_1.resolveAfter)(500);
            }
            catch (_err) {
                this.client.request.quickStop(this.deviceRef).catch();
                this.notifications$.next(`Target velocity ${velocityProfile.target} can't be reached. Aborting the calibration procedure.`);
                this.revertVelocityParameterValues();
                return;
            }
            // Read the value of the encoder register 0x52 until its value satisfies the following condition (bit 6 = 1) & (bit 8 = 0) or until 8 seconds have passed.
            osCommandResponse = yield (0, rxjs_1.lastValueFrom)((0, rxjs_1.defer)(() => this.client.request
                .runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0, 0x52, 2, 0, 10000, 1000, false)
                .pipe((0, rxjs_1.repeat)({ count: 16, delay: 500 }), (0, rxjs_1.takeWhile)((osCommandResponse) => {
                if (debug) {
                    this.notifications$.next(`Value read from the encoder register 0x52 is ${hex(osCommandResponse.kublerRegisterValue)}.`);
                }
                return ((osCommandResponse === null || osCommandResponse === void 0 ? void 0 : osCommandResponse.kublerRegisterValue) & 0b101000000) !== 0x40;
            }, true))));
            if (osCommandResponse.request === 'failed') {
                this.notifications$.next(`Reading the value of register 0x52 failed. ${osCommandResponse.errorName} (${osCommandResponse.errorCode}): ${osCommandResponse.errorDescription}`);
            }
            else if (osCommandResponse.request === 'succeeded') {
                this.notifications$.next(`The last value retrieved from register 0x52 is ${hex(osCommandResponse.kublerRegisterValue)}`);
            }
            yield this.client.request.download(this.deviceRef, 0x60ff, 0, 0);
            yield (0, util_1.resolveAfter)(200);
            this.notifications$.next('Reversing the rotation direction.');
            // Reverse the rotation direction.
            try {
                const [ec1, ec2] = yield this.notifyExtendedErrorStatusAndGetErrorCodes();
                if (((ec1 >> 16) & 0xff) === 0x0f || ((ec2 >> 16) & 0xff) === 0x0f) {
                    this.notifications$.next('There was an error in recording the correction table. Please restart the procedure.');
                    this.revertVelocityParameterValues();
                    return;
                }
            }
            catch (err) {
                if (err instanceof Error) {
                    this.notifications$.next(`Failed to notify the extended error status: ${err.message}`);
                }
            }
            velocityProfile = yield this.setVelocityProfile(this.cwVelocityProfile, 2);
            try {
                yield this.client.whenTargetReached(this.deviceRef, 500, 5000);
                yield this.notifyParameterValue(0x606c, 0); // Velocity actual value
                // Trigger the POA automatic calibration with an OS command.
                this.notifications$.next('Writing 0x00C2 to the encoder register 0x50.');
                yield this.writeEncoderRegisterValueAndValidateResponse(0x50, 0x00c2, 2);
                yield (0, util_1.resolveAfter)(500);
            }
            catch (_err) {
                this.client.request.quickStop(this.deviceRef).catch();
                this.notifications$.next(`Target velocity ${velocityProfile.target} can't be reached. Aborting the calibration procedure.`);
                this.revertVelocityParameterValues();
                return;
            }
            // Read the value of the encoder register 0x52 until its value satisfies the following condition (bit 6 = 1) & (bit 8 = 0) or until 8 seconds have passed.
            osCommandResponse = yield (0, rxjs_1.lastValueFrom)((0, rxjs_1.defer)(() => this.client.request
                .runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0, 0x52, 2, 0, 10000, 1000, false)
                .pipe((0, rxjs_1.repeat)({ count: 16, delay: 500 }), (0, rxjs_1.takeWhile)((osCommandResponse) => {
                if (debug) {
                    this.notifications$.next(`Value read from the encoder register 0x52 is ${hex(osCommandResponse.kublerRegisterValue)}.`);
                }
                return ((osCommandResponse === null || osCommandResponse === void 0 ? void 0 : osCommandResponse.kublerRegisterValue) & 0b101000000) !== 0x40;
            }, true))));
            if (osCommandResponse.request === 'failed') {
                this.notifications$.next(`Reading the value of register 0x52 failed. ${osCommandResponse.errorName} (${osCommandResponse.errorCode}): ${osCommandResponse.errorDescription}`);
            }
            else if (osCommandResponse.request === 'succeeded') {
                this.notifications$.next(`The last value retrieved from register 0x52 is ${hex(osCommandResponse.kublerRegisterValue)}`);
            }
            yield this.client.request.download(this.deviceRef, 0x60ff, 0, 0);
            yield (0, util_1.resolveAfter)(200);
            try {
                const [ec1, ec2] = yield this.notifyExtendedErrorStatusAndGetErrorCodes();
                if (((ec1 >> 16) & 0xff) === 0x0f || ((ec2 >> 16) & 0xff) === 0x0f) {
                    this.notifications$.next('There was an error in recording the correction table. Please restart the procedure.');
                    this.revertVelocityParameterValues();
                    return;
                }
                this.notifications$.next('Saving the correction table by writing 0x00D0 to the encoder register 0x50.');
                yield this.writeEncoderRegisterValueAndValidateResponse(0x50, 0x00d0, 2);
            }
            catch (err) {
                if (err instanceof Error) {
                    this.notifications$.next(`Failed to notify the extended error status: ${err.message}`);
                }
            }
            yield (0, util_1.resolveAfter)(500);
            this.notifications$.next('Sending a Quick Stop request to the device.');
            this.client.request.quickStop(this.deviceRef).catch();
            yield this.revertVelocityParameterValues();
            this.notifications$.next('The encoder calibration has been successfully completed.');
        });
    }
    /**
     * Validate device.
     */
    validateDevice() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const device = yield (0, rxjs_1.lastValueFrom)(this.client.request.resolveDevice(this.deviceRef));
            // The device must exist.
            if (!device) {
                throw new Error('No device was found when starting the encoder calibration.');
            }
            // The device must be Integro.
            if (!(0, product_1.isSomanetProductIdInRange)(device.hardwareDescription, 'Integro') &&
                !(0, product_1.isSomanetProductIdInRange)(device.hardwareDescription, 'ACTILINK-S')) {
                throw new Error('The device must be an Integro or ACTILINK-S device for the encoder calibration.');
            }
            // The encoder configuration, which is assigned to port 1, must be of type Internal encoder (5).
            const encoder1ConfigurationSensorPort = yield this.client.request.upload(this.deviceRef, 0x2110, 1);
            let encoderSource = 1;
            if (encoder1ConfigurationSensorPort === 1) {
                const encoder1ConfigurationType = yield this.client.request.upload(this.deviceRef, 0x2110, 2);
                if (encoder1ConfigurationType !== 5) {
                    throw new Error('Encoder configuration 1, which is assigned to port 1, must be of type Internal encoder (5).');
                }
            }
            else {
                const encoder2ConfigurationSensorPort = yield this.client.request.upload(this.deviceRef, 0x2112, 1);
                if (encoder2ConfigurationSensorPort === 1) {
                    const encoder2ConfigurationType = yield this.client.request.upload(this.deviceRef, 0x2112, 2);
                    if (encoder2ConfigurationType !== 5) {
                        throw new Error('Encoder configuration 2, which is assigned to port 1, must be of type Internal encoder (5).');
                    }
                    encoderSource = 2;
                }
                else {
                    throw new Error('No encoder configuration is assigned to port 1.');
                }
            }
            // The internal encoder must have a commutation function.
            const torqueControllerEncoderSource = yield this.client.request.upload(this.deviceRef, 0x2010, 12);
            if (torqueControllerEncoderSource !== encoderSource) {
                throw new Error('The internal encoder configuration must have a commutation function.');
            }
            // The internal encoder must have a velocity function.
            const velocityControllerEncoderSource = yield this.client.request.upload(this.deviceRef, 0x2011, 5);
            if (velocityControllerEncoderSource !== encoderSource) {
                throw new Error('The internal encoder configuration must have a velocity function.');
            }
            // The commutation offset must be set.
            const commutationOffsetState = yield this.client.request.upload(this.deviceRef, 0x2009, 1);
            if (commutationOffsetState !== 2) {
                throw new Error('The commutation offset state must be valid before starting the encoder calibration.');
            }
            // The velocity controller must be tuned.
            const velocityControllerKp = yield this.client.request.upload(this.deviceRef, 0x2011, 1);
            if (velocityControllerKp <= 0) {
                throw new Error('Velocity controller must be tuned before starting the encoder calibration.');
            }
        });
    }
    /**
     * Set velocity profile.
     */
    setVelocityProfile(velocityProfileConfig, accelerationConstant = 2) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const config = Object.assign({}, velocityProfileConfig); // make a copy
            // The velocity target value should not exceed the maximum motor speed.
            // If it's higher than the maximum motor speed, set it to 95% of the maximum motor speed and update acceleration and deceleration accordingly.
            if (Math.abs(config.target) > this.maxMotorSpeed) {
                const sgn = config.target < 0 ? -1 : 1;
                config.target = sgn * this.maxMotorSpeed * 0.95;
                config.acceleration = Math.abs(config.target) * accelerationConstant;
                config.deceleration = Math.abs(config.target) * accelerationConstant;
            }
            // Convert the velocity profile values using the user-configured SI unit velocity and Feed constant.
            config.target = (0, units_1.convertParameterVelocityAffectedValue)(0x60ff, 0, config.target, 0x00b44700, this.siUnitVelocity, 0xffffffff, this.feedConstantFeed);
            config.acceleration = (0, units_1.convertParameterVelocityAffectedValue)(0x6083, 0, config.acceleration, 0x00b44700, this.siUnitVelocity, 0xffffffff, this.feedConstantFeed);
            config.deceleration = (0, units_1.convertParameterVelocityAffectedValue)(0x6084, 0, config.deceleration, 0x00b44700, this.siUnitVelocity, 0xffffffff, this.feedConstantFeed);
            // Update the velocity target, and profile acceleration and deceleration values.
            this.notifications$.next(`Setting velocity target value (0x60FF:00) to ${config.target}, with the velocity profile acceleration (0x6083:00) set to ${config.acceleration} and deceleration (0x6084:00) set to ${config.deceleration}.`);
            yield (0, rxjs_1.lastValueFrom)(this.client.request.setParameterValues([
                [this.deviceRef, 0x6083, 0, config.acceleration],
                [this.deviceRef, 0x6084, 0, config.deceleration],
                [this.deviceRef, 0x6086, 0, 0],
                [this.deviceRef, 0x60ff, 0, config.target], // 0x60FF: Target velocity
            ]));
            return config;
        });
    }
    /**
     * Write encoder register value and validate response.
     */
    writeEncoderRegisterValueAndValidateResponse(address, value, length = 1) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let osCommandResponse = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 1, address, length, value, 10000, 1000, false));
            if (osCommandResponse.kublerRegisterValue !== value) {
                throw new Error(`Unable to set the encoder register ${hex(address)} value to ${hex(value)}.`);
            }
        });
    }
    notifyParameterValue(index, subindex) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const id = (0, parameter_1.makeParameterId)(index, subindex);
            const value = yield this.client.request.upload(this.deviceRef, index, subindex);
            this.notifications$.next(`Value of ${id} is ${value}.`);
        });
    }
    notifyExtendedErrorStatusAndGetErrorCodes() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const ec1Response = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0x00, 0x66, 0x04, 0, 10000, 1000, false));
            this.notifications$.next(`The value of register 0x66 (Error code 1) is ${hex(ec1Response.kublerRegisterValue)}.`);
            const ec2Response = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0x00, 0x6a, 0x04, 0, 10000, 1000, false));
            this.notifications$.next(`The value of register 0x6A (Error code 2) is ${hex(ec2Response.kublerRegisterValue)}.`);
            this.notifications$.next(`Clearing the encoder errors by writing the value 0x02 to register 0x61.`);
            yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0x01, 0x61, 0x01, 0x02, 10000, 1000, false));
            return [ec1Response.kublerRegisterValue, ec2Response.kublerRegisterValue];
        });
    }
    notifyEncoderSpeeds() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const ccwStartSpeed = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0x00, 0x5a, 0x02, 0, 10000, 1000, false));
            this.notifications$.next(`The value of register 0x5A (CCW start speed) is ${hex(ccwStartSpeed.kublerRegisterValue)}.`);
            const ccwEndSpeed = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0x00, 0x5c, 0x02, 0, 10000, 1000, false));
            this.notifications$.next(`The value of register 0x5C (CCW end speed) is ${hex(ccwEndSpeed.kublerRegisterValue)}.`);
            const cwStartSpeed = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0x00, 0x56, 0x02, 0, 10000, 1000, false));
            this.notifications$.next(`The value of register 0x56 (CW start speed) is ${hex(cwStartSpeed.kublerRegisterValue)}.`);
            const cwEndSpeed = yield (0, rxjs_1.lastValueFrom)(this.client.request.runKublerEncoderRegisterCommunicationOsCommand(this.deviceRef, 0x00, 0x58, 0x02, 0, 10000, 1000, false));
            this.notifications$.next(`The value of register 0x58 (CW end speed) is ${hex(cwEndSpeed.kublerRegisterValue)}.`);
        });
    }
    updateVelocityParameterValues() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.originalVelocityWindow = yield this.client.request.upload(this.deviceRef, 0x606d, 0);
            this.originalVelocityWindowTime = yield this.client.request.upload(this.deviceRef, 0x606e, 0);
            this.originalMaxMotorSpeed = yield this.client.request.upload(this.deviceRef, 0x6080, 0);
            this.originalQuickStopDeceleration = yield this.client.request.upload(this.deviceRef, 0x6085, 0);
            this.originalFeedConstantFeed = yield this.client.request.upload(this.deviceRef, 0x6092, 1);
            this.originalFeedConstantShaftRevolutions = yield this.client.request.upload(this.deviceRef, 0x6092, 2);
            this.originalFeedConstant = this.originalFeedConstantFeed / this.originalFeedConstantShaftRevolutions;
            this.originalSiUnitVelocity = yield this.client.request.upload(this.deviceRef, 0x60a9, 0);
            let velocityWindow = (0, units_1.convertParameterVelocityAffectedValue)(0x606d, 0, 120, 0x00b44700, this.originalSiUnitVelocity, 0xffffffff, this.originalFeedConstantFeed);
            const velocityWindowTime = 500;
            const switchToRpm = velocityWindow > 65535;
            if (switchToRpm) {
                this.notifications$.next('The user defined velocity units interfere with the maximum value of the calibration profile Velocity Window. Temporarily switching all units to RPM.');
                velocityWindow = 120;
                this.siUnitVelocity = 0x00b44700;
                this.feedConstantFeed = 0xffffffff;
                this.feedConstantShaftRevolutions = 1;
                this.feedConstant = this.feedConstantFeed / this.feedConstantShaftRevolutions;
                this.maxMotorSpeed = (0, units_1.convertParameterVelocityAffectedValue)(0x6080, 0, this.originalMaxMotorSpeed, this.originalSiUnitVelocity, this.siUnitVelocity, this.originalFeedConstant, this.feedConstant);
                this.notifications$.next(`Setting the Max motor speed (0x6080:00) to ${this.maxMotorSpeed}.`);
                yield this.client.request.download(this.deviceRef, 0x6080, 0, this.maxMotorSpeed);
                this.quickStopDeceleration = (0, units_1.convertParameterVelocityAffectedValue)(0x6085, 0, this.originalQuickStopDeceleration, this.originalSiUnitVelocity, this.siUnitVelocity, this.originalFeedConstant, this.feedConstant);
                this.notifications$.next(`Setting the Quick stop deceleration (0x6085:00) to ${this.quickStopDeceleration}.`);
                yield this.client.request.download(this.deviceRef, 0x6085, 0, this.quickStopDeceleration);
            }
            else {
                // use the original velocity values
                this.siUnitVelocity = this.originalSiUnitVelocity;
                this.feedConstantFeed = this.originalFeedConstantFeed;
                this.feedConstantShaftRevolutions = this.originalFeedConstantShaftRevolutions;
                this.feedConstant = this.originalFeedConstant;
                this.maxMotorSpeed = this.originalMaxMotorSpeed;
                this.quickStopDeceleration = this.originalQuickStopDeceleration;
            }
            this.notifications$.next(`Setting the Velocity window (0x606D:00) to ${velocityWindow}.`);
            yield this.client.request.download(this.deviceRef, 0x606d, 0, velocityWindow);
            this.notifications$.next(`Setting the Velocity window time (0x606E:00) to ${velocityWindowTime}.`);
            yield this.client.request.download(this.deviceRef, 0x606e, 0, velocityWindowTime);
            if (switchToRpm) {
                this.notifications$.next(`Setting the SI unit velocity (0x60A9:00) to ${hex(this.siUnitVelocity)}.`);
                yield this.client.request.download(this.deviceRef, 0x60a9, 0, this.siUnitVelocity);
                this.notifications$.next(`Setting the Feed constant Feed (0x6092:01) to ${this.feedConstantFeed}.`);
                yield this.client.request.download(this.deviceRef, 0x6092, 1, this.feedConstantFeed);
                this.notifications$.next(`Setting the Feed constant Shaft revolutions (0x6092:02) to ${this.feedConstantShaftRevolutions}.`);
                yield this.client.request.download(this.deviceRef, 0x6092, 2, this.feedConstantShaftRevolutions);
                yield this.client.request.forceOnDemandParametersUpdate(this.deviceRef);
            }
        });
    }
    revertVelocityParameterValues() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.notifications$.next(`Reverting the SI unit velocity (0x60A9:00) to  ${hex(this.originalSiUnitVelocity)}.`);
            yield this.client.request.download(this.deviceRef, 0x60a9, 0, this.originalSiUnitVelocity);
            this.notifications$.next(`Reverting the Feed constant Feed (0x6092:01) to ${this.originalFeedConstantFeed}.`);
            yield this.client.request.download(this.deviceRef, 0x6092, 1, this.originalFeedConstantFeed);
            this.notifications$.next(`Reverting the Feed constant Shaft revolutions (0x6092:02) to ${this.originalFeedConstantShaftRevolutions}.`);
            yield this.client.request.download(this.deviceRef, 0x6092, 2, this.originalFeedConstantShaftRevolutions);
            yield this.client.request.forceOnDemandParametersUpdate(this.deviceRef);
            this.notifications$.next(`Reverting the Max motor speed (0x6080:00) to ${this.originalMaxMotorSpeed}.`);
            yield this.client.request.download(this.deviceRef, 0x6080, 0, this.originalMaxMotorSpeed);
            this.notifications$.next(`Reverting the Quick stop deceleration (0x6085:00) to ${this.originalQuickStopDeceleration}.`);
            yield this.client.request.download(this.deviceRef, 0x6085, 0, this.originalQuickStopDeceleration);
            this.notifications$.next(`Reverting the Velocity window (0x606D:00) to ${this.originalVelocityWindow}.`);
            yield this.client.request.download(this.deviceRef, 0x606d, 0, this.originalVelocityWindow);
            this.notifications$.next(`Reverting the Velocity window time (0x606E:00) to ${this.originalVelocityWindowTime}.`);
            yield this.client.request.download(this.deviceRef, 0x606e, 0, this.originalVelocityWindowTime);
        });
    }
}
exports.IntegroEncoderCalibration = IntegroEncoderCalibration;
//# sourceMappingURL=integro-encoder-calibration.js.map