const { ATT_COEF, DEFAULT_DRIVER_PARAMS, SCALE_MAX, TWO_PI, getDriverParams, getSharedInputValues, toFiniteNumber } = require('./calculation-context') function getSpeedBase(inputValues = {}, driverParams = DEFAULT_DRIVER_PARAMS) { const candidates = [ inputValues['速度基准'], getSharedInputValues()['速度基准'], driverParams.speedBase ] for (let index = 0; index < candidates.length; index += 1) { const speedBase = toFiniteNumber(candidates[index]) if (speedBase > 0) return speedBase } return 0 } function getSampleLimits(driverParams = getDriverParams()) { const baseVoltage = driverParams.baseVoltage const samplingResistorOhm = driverParams.samplingResistorMohm / 1000 const currentSampleMax = baseVoltage / 2 / samplingResistorOhm / driverParams.opAmpGain const currentBase = currentSampleMax * 2 const voltageSampleMax = driverParams.busVoltageDividerRatio * baseVoltage return { analogInputDividerRatio: driverParams.analogInputDividerRatio, baseVoltage, busVoltageDividerRatio: driverParams.busVoltageDividerRatio, carrierFrequencyKHz: driverParams.carrierFrequencyKHz, currentBase, currentSampleMax, speedBase: getSpeedBase({}, driverParams), voltageSampleMax } } function formatWriteValue(value) { if (!Number.isFinite(value)) return '--' return String(Math.round(value)) } function formatFixedValue(value, precision = 2) { const numberValue = toFiniteNumber(value, NaN) if (!Number.isFinite(numberValue)) return '--' const text = numberValue.toFixed(precision) return Number(text) === 0 ? (0).toFixed(precision) : text } function calculateSpeedSlope(inputValues, driverParams = getDriverParams()) { const speedMin = toFiniteNumber(inputValues['速度最小值']) const speedMax = toFiniteNumber(inputValues['速度最大值']) const speedBase = getSpeedBase(inputValues, driverParams) const minVoltage = toFiniteNumber(inputValues['调速最低电压']) const maxVoltage = toFiniteNumber(inputValues['调速最高电压']) const { baseVoltage, analogInputDividerRatio } = getSampleLimits(driverParams) if (speedMax <= speedMin || maxVoltage <= minVoltage || !speedBase) return null return (speedMax - speedMin) / speedBase / ((maxVoltage - minVoltage) * analogInputDividerRatio / baseVoltage) } function calculateSpeedCommandWriteValue(actualValue, inputValues = {}, driverParams = getDriverParams()) { if (actualValue === '' || actualValue === undefined || actualValue === null) return '--' const numberValue = toFiniteNumber(actualValue, NaN) const speedBase = getSpeedBase(inputValues, driverParams) if (!Number.isFinite(numberValue) || !speedBase) return '--' return formatWriteValue(numberValue / speedBase * SCALE_MAX) } function calculateAtoGainWriteValues(atoBandwidth, inputValues = {}, driverParams = getDriverParams()) { if (atoBandwidth === '' || atoBandwidth === undefined || atoBandwidth === null) { return { kpWriteValue: '--', kiWriteValue: '--' } } const bandwidth = toFiniteNumber(atoBandwidth, NaN) const speedBase = getSpeedBase(inputValues, driverParams) const polePairs = toFiniteNumber(inputValues['极对数']) const sampleFrequency = driverParams.carrierFrequencyKHz * 1000 const tpwmValue = 1 / sampleFrequency const baseFrequency = speedBase / 60 * polePairs if (!Number.isFinite(bandwidth) || !speedBase || !polePairs || !baseFrequency) { return { kpWriteValue: '--', kiWriteValue: '--' } } return { kpWriteValue: formatWriteValue(4095 * TWO_PI * ATT_COEF * bandwidth / baseFrequency), kiWriteValue: formatWriteValue(SCALE_MAX * TWO_PI * bandwidth * bandwidth * tpwmValue / baseFrequency) } } function calculateDqGainWriteValue(item, actualValue) { if (actualValue === '' || actualValue === undefined || actualValue === null) return '--' const numberValue = toFiniteNumber(actualValue, NaN) if (!Number.isFinite(numberValue)) return '--' if (item.gainType === 'kp') return formatWriteValue(4095 * numberValue) if (item.gainType === 'ki') return formatWriteValue(SCALE_MAX * numberValue) return formatWriteValue(numberValue) } function getFloatPrecision(item) { if (item.name === 'LD' || item.name === 'LQ') return 6 if (item.name === 'RS') return 4 return 2 } function calculateParameterInputWriteValue(item, actualValue, inputValues = {}, driverParams = getDriverParams()) { if (actualValue === '' || actualValue === undefined || actualValue === null) return '--' const numberValue = toFiniteNumber(actualValue, NaN) if (!Number.isFinite(numberValue)) return '--' const { baseVoltage, analogInputDividerRatio } = getSampleLimits(driverParams) const speedBase = getSpeedBase(inputValues, driverParams) if (['开机电压', '关机电压', '调速最低电压', '调速最高电压'].includes(item.name)) { return formatWriteValue(SCALE_MAX * numberValue / baseVoltage * analogInputDividerRatio) } if (['速度最小值', '速度最大值'].includes(item.name)) { if (!speedBase) return '--' return formatWriteValue(SCALE_MAX * numberValue / speedBase) } if (item.name === 'SOUT_MAX') { const { currentBase } = getSampleLimits(driverParams) return formatWriteValue(numberValue / currentBase * SCALE_MAX) } if (item.name === '上油转速') { if (!speedBase) return '--' return formatWriteValue(SCALE_MAX * numberValue / speedBase) } if (item.type === 'uint8_t') { if (numberValue < 0 || numberValue > 0xFF) return '--' return formatWriteValue(numberValue) } if (item.type === 'float') return formatFixedValue(numberValue, getFloatPrecision(item)) return formatWriteValue(numberValue) } function calculateProtectionWriteValue(item, actualValue, driverParams = getDriverParams()) { if (!actualValue && actualValue !== 0) return '--' const { currentBase, currentSampleMax, voltageSampleMax, speedBase } = getSampleLimits(driverParams) if (['过压保护值', '欠压保护值', '过压恢复值', '欠压恢复值'].includes(item.name)) { return formatWriteValue(actualValue / voltageSampleMax * SCALE_MAX) } if (item.name === '软件过流值') { return formatWriteValue(actualValue / currentBase * SCALE_MAX) } if (['速度限制最大值', '速度限制最小值', '速度中间值'].includes(item.name)) { return formatWriteValue(actualValue / speedBase * SCALE_MAX) } if (item.name === '功率保护值') { return formatWriteValue(actualValue / currentSampleMax / voltageSampleMax * SCALE_MAX) } return item.type === 'float' ? formatFixedValue(Number(actualValue), 2) : formatWriteValue(actualValue) } function calculateParameterReadValue(item, rawValue, inputValues = {}, driverParams = getDriverParams()) { const rawNumber = toFiniteNumber(rawValue, NaN) if (!Number.isFinite(rawNumber)) return null const ratio = rawNumber / SCALE_MAX const { analogInputDividerRatio, baseVoltage, currentBase, currentSampleMax, voltageSampleMax } = getSampleLimits(driverParams) const speedBase = getSpeedBase(inputValues, driverParams) if (['开机电压', '关机电压', '调速最低电压', '调速最高电压'].includes(item.name)) { return analogInputDividerRatio ? ratio * baseVoltage / analogInputDividerRatio : null } if (['过压保护值', '欠压保护值', '过压恢复值', '欠压恢复值'].includes(item.name)) { return ratio * voltageSampleMax } if (['速度最小值', '速度最大值', '上油转速', '速度限制最大值', '速度限制最小值', '速度中间值'].includes(item.name)) { return speedBase ? ratio * speedBase : null } if (item.name === '软件过流值' || item.name === 'SOUT_MAX') { return ratio * currentBase } if (item.name === '功率保护值') { return ratio * currentSampleMax * voltageSampleMax } return null } function calculateStatusValue(name, rawValue, driverParams = getDriverParams()) { const rawNumber = toFiniteNumber(rawValue) const ratio = rawNumber / SCALE_MAX const { analogInputDividerRatio, baseVoltage, busVoltageDividerRatio, currentBase, currentSampleMax, voltageSampleMax, speedBase } = getSampleLimits(driverParams) if (name === '母线电压') return ratio * baseVoltage * busVoltageDividerRatio if (name === '母线电流') return ratio * currentBase if (name === 'NTC 电压') return ratio * baseVoltage if (name === '模拟输入电压') return analogInputDividerRatio ? ratio * baseVoltage / analogInputDividerRatio : 0 if (name === '估算速度') return ratio * speedBase if (name === '估算功率') return ratio * voltageSampleMax * currentSampleMax if (name === '频率' || name === '占空比') return rawNumber / 10 return rawNumber } module.exports = { SCALE_MAX, calculateAtoGainWriteValues, calculateDqGainWriteValue, calculateParameterInputWriteValue, calculateParameterReadValue, calculateProtectionWriteValue, calculateSpeedCommandWriteValue, calculateSpeedSlope, calculateStatusValue, formatFixedValue, getSampleLimits }