UNPKG

@betaflight/api

Version:

A high-level API to read data from betaflight flight controllers

429 lines 15.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.writePartialPidConfig = exports.writePidConfig = exports.readPidConfig = exports.writePartialAdvancedPidConfig = exports.writeAdvancedPidConfig = exports.readAdvancedPidConfig = exports.writePartialFilterConfig = exports.writeFilterConfig = exports.readFilterConfig = exports.FilterTypes = exports.AntiGravityModes = void 0; const msp_1 = require("@betaflight/msp"); const semver_1 = __importDefault(require("semver")); const codes_1 = __importDefault(require("../codes")); const utils_1 = require("../utils"); const types_1 = require("./types"); Object.defineProperty(exports, "AntiGravityModes", { enumerable: true, get: function () { return types_1.AntiGravityModes; } }); Object.defineProperty(exports, "FilterTypes", { enumerable: true, get: function () { return types_1.FilterTypes; } }); const readFilterConfig = async (port) => { const api = (0, msp_1.apiVersion)(port); const data = await (0, msp_1.execute)(port, { code: codes_1.default.MSP_FILTER_CONFIG }); const config = { gyro: { hardwareLpf: 0, hardwareLpf32khz: 0, lowpass: { hz: 0, dyn: { minHz: 0, maxHz: 0, }, type: types_1.FilterTypes.PT1, }, lowpass2: { hz: 0, type: types_1.FilterTypes.PT1, }, notch: { hz: 0, cutoff: 0, }, notch2: { hz: 0, cutoff: 0, }, rpmNotch: { harmonics: 0, minHz: 0, }, }, dterm: { lowpass: { hz: 0, dyn: { minHz: 0, maxHz: 0, }, type: types_1.FilterTypes.PT1, }, lowpass2: { hz: 0, type: types_1.FilterTypes.PT1, }, notch: { hz: 0, cutoff: 0, }, }, dyn: { lpfCurveExpo: 0, notch: { range: 0, widthPrecent: 0, q: 0, minHz: 0, maxHz: 0, }, }, yaw: { lowpass: { hz: 0, }, }, }; config.gyro.lowpass.hz = data.readU8(); config.dterm.lowpass.hz = data.readU16(); config.yaw.lowpass.hz = data.readU16(); if (semver_1.default.gte(api, "1.20.0")) { config.gyro.notch.hz = data.readU16(); config.gyro.notch.cutoff = data.readU16(); config.dterm.notch.hz = data.readU16(); config.dterm.notch.cutoff = data.readU16(); } if (semver_1.default.gte(api, "1.21.0")) { config.gyro.notch2.hz = data.readU16(); config.gyro.notch2.cutoff = data.readU16(); } if (semver_1.default.gte(api, "1.36.0")) { config.dterm.lowpass.type = data.readU8(); } if (semver_1.default.gte(api, "1.39.0")) { config.gyro.hardwareLpf = data.readU8(); const gyro32khzHardwareLpf = data.readU8(); config.gyro.lowpass.hz = data.readU16(); config.gyro.lowpass2.hz = data.readU16(); config.gyro.lowpass.type = data.readU8(); config.gyro.lowpass2.type = data.readU8(); config.dterm.lowpass2.hz = data.readU16(); config.gyro.hardwareLpf32khz = semver_1.default.lt(api, "1.41.0") ? gyro32khzHardwareLpf : 0; } if (semver_1.default.gte(api, "1.41.0")) { config.dterm.lowpass2.type = data.readU8(); config.gyro.lowpass.dyn.minHz = data.readU16(); config.gyro.lowpass.dyn.maxHz = data.readU16(); config.dterm.lowpass.dyn.minHz = data.readU16(); config.dterm.lowpass.dyn.maxHz = data.readU16(); } if (semver_1.default.gte(api, "1.42.0")) { config.dyn.notch.range = data.readU8(); config.dyn.notch.widthPrecent = data.readU8(); config.dyn.notch.q = data.readU16(); config.dyn.notch.minHz = data.readU16(); config.gyro.rpmNotch.harmonics = data.readU8(); config.gyro.rpmNotch.minHz = data.readU8(); } if (semver_1.default.gte(api, "1.43.0")) { config.dyn.notch.maxHz = data.readU16(); } if (semver_1.default.gte(api, "1.44.0")) { config.dyn.lpfCurveExpo = data.readU8(); } return config; }; exports.readFilterConfig = readFilterConfig; const writeFilterConfig = async (port, config) => { const api = (0, msp_1.apiVersion)(port); const buffer = new msp_1.WriteBuffer(); buffer .push8(config.gyro.lowpass.hz) .push16(config.dterm.lowpass.hz) .push16(config.yaw.lowpass.hz); if (semver_1.default.gte(api, "1.20.0")) { buffer .push16(config.gyro.notch.hz) .push16(config.gyro.notch.cutoff) .push16(config.dterm.notch.hz) .push16(config.dterm.notch.cutoff); } if (semver_1.default.gte(api, "1.21.0")) { buffer.push16(config.gyro.notch2.hz).push16(config.gyro.notch2.cutoff); } if (semver_1.default.gte(api, "1.36.0")) { buffer.push8(config.dterm.lowpass.type); } if (semver_1.default.gte(api, "1.39.0")) { buffer .push8(config.gyro.hardwareLpf) .push8(semver_1.default.lt(api, "1.41.0") ? config.gyro.hardwareLpf32khz : 0) .push16(config.gyro.lowpass.hz) .push16(config.gyro.lowpass2.hz) .push8(config.gyro.lowpass.type) .push8(config.gyro.lowpass2.type) .push16(config.dterm.lowpass2.hz); } if (semver_1.default.gte(api, "1.41.0")) { buffer .push8(config.dterm.lowpass2.type) .push16(config.gyro.lowpass.dyn.minHz) .push16(config.gyro.lowpass.dyn.maxHz) .push16(config.dterm.lowpass.dyn.minHz) .push16(config.dterm.lowpass.dyn.maxHz); } if (semver_1.default.gte(api, "1.42.0")) { buffer .push8(config.dyn.notch.range) .push8(config.dyn.notch.widthPrecent) .push16(config.dyn.notch.q) .push16(config.dyn.notch.minHz) .push8(config.gyro.rpmNotch.harmonics) .push8(config.gyro.rpmNotch.minHz); } if (semver_1.default.gte(api, "1.43.0")) { buffer.push16(config.dyn.notch.maxHz); } if (semver_1.default.gte(api, "1.44.0")) { buffer.push8(config.dyn.lpfCurveExpo); } await (0, msp_1.execute)(port, { code: codes_1.default.MSP_SET_FILTER_CONFIG, data: buffer }); }; exports.writeFilterConfig = writeFilterConfig; exports.writePartialFilterConfig = (0, utils_1.partialWriteFunc)(exports.readFilterConfig, exports.writeFilterConfig); const readAdvancedPidConfig = async (port) => { const api = (0, msp_1.apiVersion)(port); const data = await (0, msp_1.execute)(port, { code: codes_1.default.MSP_PID_ADVANCED }); const config = { rollPitchItermIgnoreRate: 0, yaw: { itermIgnoreRate: 0, pLimit: 0, }, deltaMethod: 0, vbatPidCompensation: 0, dtermSetpoint: { transition: 0, weight: 0, }, toleranceBand: 0, toleranceBandReduction: 0, pid: { maxVelocity: 0, maxVelocityYaw: 0, }, dMin: { roll: 0, pitch: 0, yaw: 0, gain: 0, advance: 0, }, levelAngleLimit: 0, levelSensitivity: 0, iterm: { throttleGain: 0, throttleThreshold: 0, acceleratorGain: 0, rotation: 0, relax: 0, relaxType: 0, relaxCutoff: 0, }, smartFeedForward: 0, absoluteControlGain: 0, throttleBoost: 0, acroTrainerAngleLimit: 0, antiGravityMode: types_1.AntiGravityModes.SMOOTH, useIntegratedYaw: false, integratedYawRelax: 0, motorOutputLimit: 0, autoProfileCellCount: 0, idleMinRpm: 0, feedForward: { roll: 0, pitch: 0, yaw: 0, transition: 0, interpolateSp: 0, smoothFactor: 0, boost: 0, }, vbatSagCompensation: 0, thrustLinearization: 0, }; if (semver_1.default.gte(api, "1.16.0")) { config.rollPitchItermIgnoreRate = data.readU16(); config.yaw.itermIgnoreRate = data.readU16(); config.yaw.pLimit = data.readU16(); config.deltaMethod = data.readU8(); config.vbatPidCompensation = data.readU8(); } if (semver_1.default.gte(api, "1.20.0")) { if (semver_1.default.gte(api, "1.40.0")) { config.feedForward.transition = data.readU8(); } else { config.dtermSetpoint.transition = data.readU8(); } config.dtermSetpoint.weight = data.readU8(); config.toleranceBand = data.readU8(); config.toleranceBandReduction = data.readU8(); config.iterm.throttleGain = data.readU8(); config.pid.maxVelocity = data.readU16(); config.pid.maxVelocityYaw = data.readU16(); } if (semver_1.default.gte(api, "1.24.0")) { config.levelAngleLimit = data.readU8(); config.levelSensitivity = data.readU8(); } if (semver_1.default.gte(api, "1.36.0")) { config.iterm.throttleThreshold = data.readU16(); config.iterm.acceleratorGain = data.readU16(); } if (semver_1.default.gte(api, "1.39.0")) { config.dtermSetpoint.weight = data.readU16(); } if (semver_1.default.gte(api, "1.40.0")) { config.iterm.rotation = data.readU8(); config.smartFeedForward = data.readU8(); config.iterm.relax = data.readU8(); config.iterm.relaxType = data.readU8(); config.absoluteControlGain = data.readU8(); config.throttleBoost = data.readU8(); config.acroTrainerAngleLimit = data.readU8(); config.feedForward.roll = data.readU16(); config.feedForward.pitch = data.readU16(); config.feedForward.yaw = data.readU16(); config.antiGravityMode = data.readU8(); } if (semver_1.default.gte(api, "1.41.0")) { config.dMin.roll = data.readU8(); config.dMin.pitch = data.readU8(); config.dMin.yaw = data.readU8(); config.dMin.gain = data.readU8(); config.dMin.advance = data.readU8(); config.useIntegratedYaw = data.readU8() !== 0; config.integratedYawRelax = data.readU8(); } if (semver_1.default.gte(api, "1.42.0")) { config.iterm.relaxCutoff = data.readU8(); } if (semver_1.default.gte(api, "1.43.0")) { config.motorOutputLimit = data.readU8(); config.autoProfileCellCount = data.read8(); config.idleMinRpm = data.readU8(); } if (semver_1.default.gte(api, "1.44.0")) { config.feedForward.interpolateSp = data.readU8(); config.feedForward.smoothFactor = data.readU8(); config.feedForward.boost = data.readU8(); config.vbatSagCompensation = data.readU8(); config.thrustLinearization = data.readU8(); } return config; }; exports.readAdvancedPidConfig = readAdvancedPidConfig; const writeAdvancedPidConfig = async (port, config) => { const api = (0, msp_1.apiVersion)(port); if (semver_1.default.lt(api, "1.16.0")) { // This API doesn't do anything return; } const buffer = new msp_1.WriteBuffer(); buffer .push16(config.rollPitchItermIgnoreRate) .push16(config.yaw.itermIgnoreRate) .push16(config.yaw.pLimit) .push8(config.deltaMethod) .push8(config.vbatPidCompensation); if (semver_1.default.gte(api, "1.20.0")) { if (semver_1.default.gte(api, "1.40.0")) { buffer.push8(config.feedForward.transition); } else { buffer.push8(config.dtermSetpoint.transition); } buffer .push8(Math.min(config.dtermSetpoint.weight, 254)) .push8(config.toleranceBand) .push8(config.toleranceBandReduction) .push8(config.iterm.throttleGain) .push16(config.pid.maxVelocity) .push16(config.pid.maxVelocityYaw); } if (semver_1.default.gte(api, "1.24.0")) { buffer.push8(config.levelAngleLimit).push8(config.levelSensitivity); } if (semver_1.default.gte(api, "1.36.0")) { buffer .push16(config.iterm.throttleThreshold) .push16(config.iterm.acceleratorGain); } if (semver_1.default.gte(api, "1.39.0")) { buffer.push16(config.dtermSetpoint.weight); } if (semver_1.default.gte(api, "1.40.0")) { buffer .push8(config.iterm.rotation) .push8(config.smartFeedForward) .push8(config.iterm.relax) .push8(config.iterm.relaxType) .push8(config.absoluteControlGain) .push8(config.throttleBoost) .push8(config.acroTrainerAngleLimit) .push16(config.feedForward.roll) .push16(config.feedForward.pitch) .push16(config.feedForward.yaw) .push8(config.antiGravityMode); } if (semver_1.default.gte(api, "1.41.0")) { buffer .push8(config.dMin.roll) .push8(config.dMin.pitch) .push8(config.dMin.yaw) .push8(config.dMin.gain) .push8(config.dMin.advance) .push8(config.useIntegratedYaw ? 1 : 0) .push8(config.integratedYawRelax); } if (semver_1.default.gte(api, "1.42.0")) { buffer.push8(config.iterm.relaxCutoff); } if (semver_1.default.gte(api, "1.43.0")) { buffer .push8(config.motorOutputLimit) .push8(config.autoProfileCellCount) .push8(config.idleMinRpm); } if (semver_1.default.gte(api, "1.44.0")) { buffer .push8(config.feedForward.interpolateSp) .push8(config.feedForward.smoothFactor) .push8(config.feedForward.boost) .push8(config.vbatSagCompensation) .push8(config.thrustLinearization); } await (0, msp_1.execute)(port, { code: codes_1.default.MSP_SET_PID_ADVANCED, data: buffer }); }; exports.writeAdvancedPidConfig = writeAdvancedPidConfig; exports.writePartialAdvancedPidConfig = (0, utils_1.partialWriteFunc)(exports.readAdvancedPidConfig, exports.writeAdvancedPidConfig); const pidNames = ["roll", "pitch", "yaw", "level", "mag"]; const readPidConfig = async (port) => { const data = await (0, msp_1.execute)(port, { code: codes_1.default.MSP_PID }); return pidNames.reduce((config, key) => ({ ...config, [key]: { p: data.readU8(), i: data.readU8(), d: data.readU8(), }, }), {}); }; exports.readPidConfig = readPidConfig; const writePidConfig = async (port, config) => { const buffer = new msp_1.WriteBuffer(); pidNames.forEach((key) => { const { p, i, d } = config[key]; buffer.push8(p).push8(i).push8(d); }); await (0, msp_1.execute)(port, { code: codes_1.default.MSP_SET_PID, data: buffer }); }; exports.writePidConfig = writePidConfig; exports.writePartialPidConfig = (0, utils_1.partialWriteFunc)(exports.readPidConfig, exports.writePidConfig); //# sourceMappingURL=index.js.map