conversions.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. const {
  2. ATT_COEF,
  3. DEFAULT_DRIVER_PARAMS,
  4. SCALE_MAX,
  5. TWO_PI,
  6. getDriverParams,
  7. getSharedInputValues,
  8. toFiniteNumber
  9. } = require('./calculation-context')
  10. const {
  11. rawToTemperature,
  12. temperatureToRaw
  13. } = require('./thermistor')
  14. function getSpeedBase(inputValues = {}, driverParams = DEFAULT_DRIVER_PARAMS) {
  15. const candidates = [
  16. inputValues['速度基准'],
  17. getSharedInputValues()['速度基准'],
  18. driverParams.speedBase
  19. ]
  20. for (let index = 0; index < candidates.length; index += 1) {
  21. const speedBase = toFiniteNumber(candidates[index])
  22. if (speedBase > 0) return speedBase
  23. }
  24. return 0
  25. }
  26. function getSampleLimits(driverParams = getDriverParams()) {
  27. const baseVoltage = driverParams.baseVoltage
  28. const samplingResistorOhm = driverParams.samplingResistorMohm / 1000
  29. const currentSampleMax = baseVoltage / 2 / samplingResistorOhm / driverParams.opAmpGain
  30. const currentBase = currentSampleMax * 2
  31. const voltageSampleMax = driverParams.busVoltageDividerRatio * baseVoltage
  32. return {
  33. analogInputDividerRatio: driverParams.analogInputDividerRatio,
  34. baseVoltage,
  35. busVoltageDividerRatio: driverParams.busVoltageDividerRatio,
  36. carrierFrequencyKHz: driverParams.carrierFrequencyKHz,
  37. currentBase,
  38. currentSampleMax,
  39. speedBase: getSpeedBase({}, driverParams),
  40. voltageSampleMax
  41. }
  42. }
  43. function formatWriteValue(value) {
  44. if (!Number.isFinite(value)) return '--'
  45. return String(Math.round(value))
  46. }
  47. function formatFixedValue(value, precision = 2) {
  48. const numberValue = toFiniteNumber(value, NaN)
  49. if (!Number.isFinite(numberValue)) return '--'
  50. const text = numberValue.toFixed(precision)
  51. return Number(text) === 0 ? (0).toFixed(precision) : text
  52. }
  53. function calculateSpeedSlope(inputValues, driverParams = getDriverParams()) {
  54. const speedMin = toFiniteNumber(inputValues['速度最小值'])
  55. const speedMax = toFiniteNumber(inputValues['速度最大值'])
  56. const speedBase = getSpeedBase(inputValues, driverParams)
  57. const minVoltage = toFiniteNumber(inputValues['调速最低电压'])
  58. const maxVoltage = toFiniteNumber(inputValues['调速最高电压'])
  59. const { baseVoltage, analogInputDividerRatio } = getSampleLimits(driverParams)
  60. if (speedMax <= speedMin || maxVoltage <= minVoltage || !speedBase) return null
  61. return (speedMax - speedMin) / speedBase / ((maxVoltage - minVoltage) * analogInputDividerRatio / baseVoltage)
  62. }
  63. function calculateSpeedCommandWriteValue(actualValue, inputValues = {}, driverParams = getDriverParams()) {
  64. if (actualValue === '' || actualValue === undefined || actualValue === null) return '--'
  65. const numberValue = toFiniteNumber(actualValue, NaN)
  66. const speedBase = getSpeedBase(inputValues, driverParams)
  67. if (!Number.isFinite(numberValue) || !speedBase) return '--'
  68. return formatWriteValue(numberValue / speedBase * SCALE_MAX)
  69. }
  70. function calculateAtoGainWriteValues(atoBandwidth, inputValues = {}, driverParams = getDriverParams()) {
  71. if (atoBandwidth === '' || atoBandwidth === undefined || atoBandwidth === null) {
  72. return {
  73. kpWriteValue: '--',
  74. kiWriteValue: '--'
  75. }
  76. }
  77. const bandwidth = toFiniteNumber(atoBandwidth, NaN)
  78. const speedBase = getSpeedBase(inputValues, driverParams)
  79. const polePairs = toFiniteNumber(inputValues['极对数'])
  80. const sampleFrequency = driverParams.carrierFrequencyKHz * 1000
  81. const tpwmValue = 1 / sampleFrequency
  82. const baseFrequency = speedBase / 60 * polePairs
  83. if (!Number.isFinite(bandwidth) || !speedBase || !polePairs || !baseFrequency) {
  84. return {
  85. kpWriteValue: '--',
  86. kiWriteValue: '--'
  87. }
  88. }
  89. return {
  90. kpWriteValue: formatWriteValue(4095 * TWO_PI * ATT_COEF * bandwidth / baseFrequency),
  91. kiWriteValue: formatWriteValue(SCALE_MAX * TWO_PI * bandwidth * bandwidth * tpwmValue / baseFrequency)
  92. }
  93. }
  94. function calculateDqGainWriteValue(item, actualValue) {
  95. if (actualValue === '' || actualValue === undefined || actualValue === null) return '--'
  96. const numberValue = toFiniteNumber(actualValue, NaN)
  97. if (!Number.isFinite(numberValue)) return '--'
  98. if (item.gainType === 'kp') return formatWriteValue(4095 * numberValue)
  99. if (item.gainType === 'ki') return formatWriteValue(SCALE_MAX * numberValue)
  100. return formatWriteValue(numberValue)
  101. }
  102. function getFloatPrecision(item) {
  103. if (item.name === 'LD' || item.name === 'LQ') return 6
  104. if (item.name === 'RS') return 4
  105. return 2
  106. }
  107. function calculateParameterInputWriteValue(item, actualValue, inputValues = {}, driverParams = getDriverParams()) {
  108. if (actualValue === '' || actualValue === undefined || actualValue === null) return '--'
  109. const numberValue = toFiniteNumber(actualValue, NaN)
  110. if (!Number.isFinite(numberValue)) return '--'
  111. const { baseVoltage, analogInputDividerRatio } = getSampleLimits(driverParams)
  112. const speedBase = getSpeedBase(inputValues, driverParams)
  113. if (['开机电压', '关机电压', '调速最低电压', '调速最高电压'].includes(item.name)) {
  114. return formatWriteValue(SCALE_MAX * numberValue / baseVoltage * analogInputDividerRatio)
  115. }
  116. if (['速度最小值', '速度最大值'].includes(item.name)) {
  117. if (!speedBase) return '--'
  118. return formatWriteValue(SCALE_MAX * numberValue / speedBase)
  119. }
  120. if (item.name === 'SOUT_MAX') {
  121. const { currentBase } = getSampleLimits(driverParams)
  122. return formatWriteValue(numberValue / currentBase * SCALE_MAX)
  123. }
  124. if (item.name === '上油转速') {
  125. if (!speedBase) return '--'
  126. return formatWriteValue(SCALE_MAX * numberValue / speedBase)
  127. }
  128. if (item.type === 'uint8_t') {
  129. if (numberValue < 0 || numberValue > 0xFF) return '--'
  130. return formatWriteValue(numberValue)
  131. }
  132. if (item.type === 'float') return formatFixedValue(numberValue, getFloatPrecision(item))
  133. return formatWriteValue(numberValue)
  134. }
  135. function calculateProtectionWriteValue(item, actualValue, driverParams = getDriverParams()) {
  136. if (!actualValue && actualValue !== 0) return '--'
  137. const { currentBase, currentSampleMax, voltageSampleMax, speedBase } = getSampleLimits(driverParams)
  138. if (['过压保护值', '欠压保护值', '过压恢复值', '欠压恢复值'].includes(item.name)) {
  139. return formatWriteValue(actualValue / voltageSampleMax * SCALE_MAX)
  140. }
  141. if (item.name === '软件过流值') {
  142. return formatWriteValue(actualValue / currentBase * SCALE_MAX)
  143. }
  144. if (['速度限制最大值', '速度限制最小值', '速度中间值'].includes(item.name)) {
  145. return formatWriteValue(actualValue / speedBase * SCALE_MAX)
  146. }
  147. if (item.name === '功率保护值') {
  148. return formatWriteValue(actualValue / currentSampleMax / voltageSampleMax * SCALE_MAX)
  149. }
  150. if (item.name === '温度保护值' || item.name === '温度恢复值') {
  151. const rawValue = temperatureToRaw(actualValue, SCALE_MAX)
  152. return rawValue === null ? '--' : formatWriteValue(rawValue)
  153. }
  154. return item.type === 'float' ? formatFixedValue(Number(actualValue), 2) : formatWriteValue(actualValue)
  155. }
  156. function calculateParameterReadValue(item, rawValue, inputValues = {}, driverParams = getDriverParams()) {
  157. const rawNumber = toFiniteNumber(rawValue, NaN)
  158. if (!Number.isFinite(rawNumber)) return null
  159. const ratio = rawNumber / SCALE_MAX
  160. const {
  161. analogInputDividerRatio,
  162. baseVoltage,
  163. currentBase,
  164. currentSampleMax,
  165. voltageSampleMax
  166. } = getSampleLimits(driverParams)
  167. const speedBase = getSpeedBase(inputValues, driverParams)
  168. if (['开机电压', '关机电压', '调速最低电压', '调速最高电压'].includes(item.name)) {
  169. return analogInputDividerRatio ? ratio * baseVoltage / analogInputDividerRatio : null
  170. }
  171. if (['过压保护值', '欠压保护值', '过压恢复值', '欠压恢复值'].includes(item.name)) {
  172. return ratio * voltageSampleMax
  173. }
  174. if (['速度最小值', '速度最大值', '上油转速', '速度限制最大值', '速度限制最小值', '速度中间值'].includes(item.name)) {
  175. return speedBase ? ratio * speedBase : null
  176. }
  177. if (item.name === '软件过流值' || item.name === 'SOUT_MAX') {
  178. return ratio * currentBase
  179. }
  180. if (item.name === '功率保护值') {
  181. return ratio * currentSampleMax * voltageSampleMax
  182. }
  183. if (item.name === '温度保护值' || item.name === '温度恢复值') {
  184. return rawToTemperature(rawNumber, SCALE_MAX)
  185. }
  186. return null
  187. }
  188. function calculateStatusValue(name, rawValue, driverParams = getDriverParams()) {
  189. const rawNumber = toFiniteNumber(rawValue)
  190. const ratio = rawNumber / SCALE_MAX
  191. const {
  192. analogInputDividerRatio,
  193. baseVoltage,
  194. busVoltageDividerRatio,
  195. currentBase,
  196. currentSampleMax,
  197. voltageSampleMax,
  198. speedBase
  199. } = getSampleLimits(driverParams)
  200. if (name === '母线电压') return ratio * baseVoltage * busVoltageDividerRatio
  201. if (name === '母线电流') return ratio * currentBase
  202. if (name === 'NTC 温度') return rawToTemperature(rawNumber, SCALE_MAX)
  203. if (name === '模拟输入电压') return analogInputDividerRatio ? ratio * baseVoltage / analogInputDividerRatio : 0
  204. if (name === '估算速度') return ratio * speedBase
  205. if (name === '估算功率') return ratio * voltageSampleMax * currentSampleMax
  206. if (name === '频率' || name === '占空比') return rawNumber / 10
  207. return rawNumber
  208. }
  209. module.exports = {
  210. SCALE_MAX,
  211. calculateAtoGainWriteValues,
  212. calculateDqGainWriteValue,
  213. calculateParameterInputWriteValue,
  214. calculateParameterReadValue,
  215. calculateProtectionWriteValue,
  216. calculateSpeedCommandWriteValue,
  217. calculateSpeedSlope,
  218. calculateStatusValue,
  219. formatFixedValue
  220. }