Files
Motor_v2/Robot_V2/sys/config.h
T
cbb b71fba2016 feat(FOC): 添加角度同步Uq前馈补偿和速度环优化
- 实现update_angle_sync_uq_feedforward函数,支持mode2和mode3的角度同步  Uq前馈补偿,按物理360°查表学习负载/阻力差异
- 实现get_mode3_velocity_p函数,mode3低速时降低速度环P参数减少抖动
- 在velocity_control和angle_control_with_velocity_limit中集成Uq前馈补偿
- 优化normalizeAngle360函数,大角度时先扣整圈数避免while循环过多
- 调整配置参数,降低DEFAULT_vel_loop_p并添加详细的Uq前馈补偿配置
- 更新电源电压参数使用本周期采样值,避免电压滞后影响
2026-05-24 04:56:33 +08:00

293 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file sys/config.h
* @brief 系统服务与平台支持源文件
* @note 本文件仅补充 Doxygen 文档注释,不改变代码逻辑。
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include "gd32c10x_eval.h"
#include <cstdint>
// 如果使用 CMSIS DSP 库,需要定义 ARM_MATH_CM4
#define ARM_MATH_CM4
#define EEP_DEBUG 0
#define OTA_DEBUG 0
#define SLEEP_DEBUG 0
#define ANG_SENS_DEBUG 0
#define CAN_DEBUG 0
#define MAIN_DEBUG 0
#define FOC_DEBUG 0
// 版本号定义 - 可根据实际项目进行调整
constexpr u16 SOFTWARE_VERSION_MAJOR = 26;
constexpr u16 SOFTWARE_VERSION_MINOR = 5;
constexpr u16 SOFTWARE_VERSION_PATCH = 24;
constexpr u16 SOFTWARE_VERSION_BUILD = 2;
constexpr u16 HARDWARE_VERSION_MAJOR = 25;
constexpr u16 HARDWARE_VERSION_MINOR = 12;
constexpr u16 HARDWARE_VERSION_PATCH = 01;
constexpr u16 HARDWARE_VERSION_BUILD = 0;
constexpr u16 BOOT_VERSION_MAJOR = 26;
constexpr u16 BOOT_VERSION_MINOR = 1;
constexpr u16 BOOT_VERSION_PATCH = 12;
constexpr u16 BOOT_VERSION_BUILD = 0;
// Flash 分区配置
constexpr u32 BOOTLOADER_SIZE = 0x6000; // 24KB
constexpr u32 BOOTLOADER_START_ADDR = 0x08000000; // BOOT 起始地址
constexpr u32 APPLATEST_START_ADDR = 0x08012000; // APP 起始地址
constexpr u32 APPBACK_START_ADDR = 0x08006000; // APPBACK 起始地址
constexpr u32 APP_MAX_SIZE = 0xC000; // 48KB
constexpr u32 FMC_PAGE_SIZE = 0x400; // 1KB
constexpr u32 SLEEP_CONFIG_START = 0x0801E400; // 睡眠配置起始地址
constexpr u32 SLEEP_CONFIG_END = 0x0801E800; // 睡眠配置结束地址
constexpr u32 FLASH_EMPTY = 0xFFFFFFFF; // 空数据
constexpr u32 SLEEP_ENABLE = 0x11111111; // 睡眠使能
constexpr u32 SLEEP_DISABLE = 0x00000000; // 睡眠禁止
// 节点 ID 配置 (用于多电机 CAN 总线隔离)
// 使用 CAN ID 高 16 位 (bits 31-16) 存储节点 ID,低 16 位 (bits 15-0) 存储基础 ID
// 格式:[节点 ID(16 位)][基础 ID(16 位)],例如:node_id=1, base_id=0x0200 → 0x00010200
//
// 节点 ID 存储方案:
// - 使用独立 Flash 页 (NODE_ID_PAGE_ADDR) 存储节点 ID,与EEPROM完全隔离
// - 采用双重备份机制 (主备份 + 备用备份)
// - 使用魔数 (NODE_ID_MAGIC) 验证数据有效性,防止位翻转导致错读
// - 使用写入计数器区分最新数据
constexpr u32 NODE_ID_PAGE_ADDR = 0x0801E800; // 节点 ID 存储页 (1KB,独立区域)
constexpr u32 NODE_ID_PRIMARY_ADDR = 0x0801E800; // 主存储地址
constexpr u32 NODE_ID_BACKUP_ADDR = 0x0801E840; // 备份存储地址 (偏移64字节)
constexpr u32 NODE_ID_MAGIC = 0x4E4F4445; // 魔数 'NODE' 用于验证数据有效性
constexpr u16 DEFAULT_NODE_ID = 1; // 默认节点 ID
constexpr u16 BROADCAST_NODE_ID = 0x1FFF; // 广播 ID (所有节点响应)
constexpr u16 MAX_NODE_ID = 0x1FFE; // 最大有效节点 ID (0~0x1FFE)
// 节点 ID 存储结构 (存储在Flash中的格式)
// 地址偏移 0x00: 魔数 (0x4E4F4445 = 'NODE')
// 地址偏移 0x04: 节点 ID (u16)
// 地址偏移 0x06: 保留 (u16,填充为0xFFFF)
// 地址偏移 0x08: 写入计数器 (u32,用于区分最新数据)
// 地址偏移 0x0C: CRC32 校验 (u32)
constexpr u8 NODE_ID_STRUCT_SIZE = 0x10; // 结构体大小 16 字节
constexpr u8 NODE_ID_MAGIC_OFFSET = 0x00; // 魔数偏移
constexpr u8 NODE_ID_VALUE_OFFSET = 0x04; // 节点ID值偏移
constexpr u8 NODE_ID_COUNTER_OFFSET = 0x08; // 写入计数器偏移
constexpr u8 NODE_ID_CRC_OFFSET = 0x0C; // CRC偏移
// BOOT 相关
constexpr u32 OTA_CONFIG_NUM = 6;
constexpr u32 n_APP_LATEST_AVAL_ADDR = 0x0801E000; // 最新 APP 可用地址
constexpr u32 n_APP_BACKUP_AVAL_ADDR = 0x0801E004; // 备份 APP 可用地址
constexpr u32 n_APP_LATEST_EN_ADDR = 0x0801E008; // 最新 APP 激活
constexpr u32 n_APP_BACKUP_EN_ADDR = 0x0801E00C; // 备份 APP 激活
constexpr u32 n_APP_LATEST_CHECK_ADDR = 0x0801E010; // 最新 APP 校验
constexpr u32 n_APP_BACKUP_CHECK_ADDR = 0x0801E014; // 备份 APP 校验
constexpr u32 OTA_NOT_AVAL = 0xFFFFFFFF;
constexpr u32 OTA_AVAL = 0x00000000; // 全零表示可用
// 参数配置
constexpr u8 PP = 11;
constexpr float DIR = 1.0f; // 默认方向:-1.0f 反转,1.0f 正转
constexpr u16 REDUCTION_RATIO = 25;
constexpr float CURRENT_OFFSET = -3.31f / 2.0f; // 当前电流传感器的零点偏移
constexpr float HOLD_PWM_DUTY = 0.1f;
constexpr u16 ANGLESENS_OFFSET = 0;
constexpr float ANGLESENS_CALIBRATION_ANGLE = 83.0f;
constexpr float KE_FACTOR = 0.0f;
// 角度/速度 α-β 观测器参数
constexpr float ANGLE_KALMAN_INITIAL_STATE = 0.0f;
constexpr float ANGLE_KALMAN_INITIAL_COVARIANCE = 0.0f;
constexpr float ANGLE_KALMAN_PROCESS_NOISE_Q = 0.0f;
constexpr float ANGLE_KALMAN_MEASUREMENT_NOISE_R = 0.0f;
constexpr float ANGLE_OBSERVER_ALPHA = 0.75f; // 角度校正增益,越大越跟测量
constexpr float ANGLE_OBSERVER_BETA = 0.002f; // 速度校正增益,原0.001微调至0.002
// 旧速度 Kalman 参数保留用于接口兼容;主速度输出现在直接来自 α-β 观测器
constexpr float VELOCITY_KALMAN_INITIAL_STATE = 0.0f;
constexpr float VELOCITY_KALMAN_INITIAL_COVARIANCE = 1e-3f;
constexpr float VELOCITY_KALMAN_PROCESS_NOISE_Q =
5e-4f; // 略增大,减少拖尾
constexpr float VELOCITY_KALMAN_MEASUREMENT_NOISE_R =
0.05f; // 明显小于旧值,避免压得太死
// 电流卡尔曼滤波器参数
constexpr float CURRENT_KALMAN_INITIAL_STATE = 0.0f;
constexpr float CURRENT_KALMAN_INITIAL_COVARIANCE = 100.0f; // 增大初始协方差
constexpr float CURRENT_KALMAN_PROCESS_NOISE_Q = 10.0f; // 降低过程噪声
constexpr float CURRENT_KALMAN_MEASUREMENT_NOISE_R = 5e-5f; // 增大测量噪声
// PID 配置
constexpr float DEFAULT_current_loop_p = 0.1f / 100 * 12; // 电流 P
constexpr float current_loop_Ki = 0.55f; // 电流 P
constexpr float current_loop_Kd = 3e-4f; // 电流 P
constexpr float DEFAULT_vel_loop_p = 0.005f / 100 * 12; // 速度 P
constexpr float vel_loop_Ku = 3.600000e-03 * 0.7 * 100 / 12;
constexpr float vel_loop_Tu = 17.0f * 1e-3f;
constexpr float vel_loop_Ki = 1.2 * vel_loop_Ku / vel_loop_Tu;
constexpr float vel_loop_Kd = 0.075 * vel_loop_Ku * vel_loop_Tu * 2;
// mode2 角度同步 Uq 前馈补偿:固定 Uq 下的真实速度波动不应从反馈中滤掉,
// 而应按物理 360° 提前补偿负载/阻力差异,降低速度 PID 的周期性纠偏量。
constexpr bool MODE2_UQ_FF_ENABLE = true;
constexpr bool MODE2_UQ_FF_LEARN_ENABLE = true;
constexpr u16 MODE2_UQ_FF_TABLE_SIZE = 180;
constexpr float MODE2_UQ_FF_LEARN_ALPHA = 0.01f; // 越小越慢,避免误学瞬态
constexpr float MODE2_UQ_FF_MIN_TARGET = 1.5f; // 目标速度过低时不学习
constexpr float MODE2_UQ_FF_GAIN = 0.003f; // 速度误差(deg/s)到前馈电压(V)的学习比例
constexpr float MODE2_UQ_FF_MAX = 3.5f; // 前馈补偿电压限幅(V)
constexpr float MODE2_UQ_FF_STOP_SPEED = 2.0f; // 目标/实际速度低于该值时不输出前馈
constexpr float MODE2_UQ_FF_BRAKE_ERR = 3.0f; // 明显超速/刹车时不输出前馈,单位同 velocity_error
// mode3 角度同步 Uq 前馈补偿:单独建表,避免和 mode2 互相污染。
constexpr bool MODE3_UQ_FF_ENABLE = true;
constexpr bool MODE3_UQ_FF_LEARN_ENABLE = true;
constexpr u16 MODE3_UQ_FF_TABLE_SIZE = 180;
constexpr float MODE3_UQ_FF_LEARN_ALPHA = 0.01f;
constexpr float MODE3_UQ_FF_MIN_TARGET = 2.5f; // mode3 内部目标速度过低时不学习
constexpr float MODE3_UQ_FF_GAIN = 0.3f; // mode3 速度误差未乘减速比,故增益独立于 mode2
constexpr float MODE3_UQ_FF_MAX = 3.5f;
constexpr float MODE3_UQ_FF_STOP_SPEED = 2.0f; // mode3 内部目标/实际速度低于该值时不输出前馈
constexpr float MODE3_UQ_FF_BRAKE_ERR = 3.0f; // 明显超速/刹车时不输出前馈,单位同 velocity_error
constexpr float DEFAULT_vel_angloop_p = 0.4f / 100; // 速度 速度 - 角度 P
constexpr float vel_angloop_Ki = 5.0f; // 速度 速度 - 角度 I
constexpr float vel_angloop_Kd = 5e-05f; // 速度 速度 - 角度 D
// mode3 低速/静止附近速度 P 降低,减少速度反馈噪声、齿槽和摩擦导致的来回拉扯。
constexpr bool MODE3_LOW_SPEED_P_SCALE_ENABLE = true;
constexpr float MODE3_LOW_SPEED_P_MIN_SCALE = 0.2f;
constexpr float MODE3_LOW_SPEED_P_LOW = 1.0f;
constexpr float MODE3_LOW_SPEED_P_FULL = 5.0f;
constexpr float DEFAULT_angle_angloop_p =
150.0f / 100 * 12; // 角度 速度 - 角度 P
constexpr float ang_angloop_Ki = 0.00f; // 角度 速度 - 角度 I
constexpr float ang_angloop_Kd = 8e-04f; // 角度 速度 - 角度 D
constexpr float DEFAULT_angle_loop_p = 60.0f / 100 * 12; // 角度 P
constexpr float DEFAULT_angle_MIT_p = 100.0f / 100 * 12; // 角度 MIT P
constexpr float angle_MIT_Ki = 0.0f;
constexpr float angle_MIT_Kd = 8e-04f;
constexpr float DEFAULT_vel_MIT_p = 5.0f / 100; // 速度 MIT P
constexpr float vel_MIT_Ki = 15.0f;
constexpr float vel_MIT_Kd = 1e-04f;
constexpr float DEFAULT_current_MIT_p = 0.2f / 100 * 12; // 电流 MIT P
constexpr float current_MIT_Ki = 0.1f;
constexpr float current_MIT_Kd = 3e-4f;
// 常量定义
constexpr u8 SIZE_FLOAT = sizeof(float);
constexpr u8 SIZE_U32 = sizeof(uint32_t);
constexpr float ADC_MAX = 65536.0f;
constexpr float PI = 3.14159265358979323846f;
constexpr float INV_PI_3 = 3.0f / PI;
constexpr float PI_3 = PI / 3.0f;
constexpr float _1_SQRT3 = 0.57735026919f; // 1/sqrt(3)
constexpr float _3PI_2 = 4.71238898038f;
constexpr float SQRT3 = 1.7320508075688772f;
constexpr float SQRT3DV2 = 0.8660254037844386f; // sqrt(3)/2
constexpr float COS_PI_3 = 0.5f;
constexpr float ANGLE_FACTOR = 25.0f / 180.0f * PI;
constexpr float DEG2RAD = 1.0f / 180.0f * PI;
constexpr float RAD2DEG = 180.0f / PI; // 修正 RAD2DEG 定义,应该是 180/π
constexpr u8 DEFAULT_VALUE = 0;
constexpr u8 CONFIG_SAVED_NUM = 6;
// 三角函数快速计算 LUT
constexpr u16 LUT_SIZE = 1024;
constexpr u16 LUT_MASK = (LUT_SIZE - 1);
constexpr u16 LUT_SCALE = (LUT_SIZE / (2.0f * PI));
// CAN 相关
// 注意:以下为 CAN 基础 ID(只保留低 16 位),实际发送/接收时会自动叠加节点 ID
// 到高 16 位 格式:[节点 ID(16 位)][基础 ID(16 位)] 例如:节点 ID=1,发送命令
// ID = (1 << 16) | CANFD_CMD_ID = 0x00010200
constexpr u16 DEV_CAN0_ID = 0x0000;
constexpr u16 DEV_CAN0_MASK = 0x0000;
constexpr u16 DEV_CAN_LOOPBACK_ID = 0x0000;
// 反馈基础 ID
constexpr u16 CANFD_STATUS_ID = 0x0100; // 状态反馈基础 ID
constexpr u16 CANFD_CONFIG_ID = 0x0101; // 配置信息基础 ID
constexpr u16 CANFD_VERSION_ID = 0x00FF; // 版本信息基础 ID
// 命令基础 ID
constexpr u16 CANFD_CMD_ID = 0x0200; // 控制命令基础 ID
constexpr u16 CANFD_RESET_ID = 0x0301; // 重置命令基础 ID
// 节点 ID 管理基础 ID
constexpr u16 CANFD_SET_NODE_ID = 0x0400; // 设置节点 ID 基础 ID
constexpr u16 CANFD_GET_NODE_ID = 0x0401; // 查询节点 ID 基础 ID
// OTA 相关基础 ID 不受到node ID影响
constexpr u16 CANFD_BOOT_ID = 0x0000; // BOOT 模式基础 ID (进入 BOOT 使用此 ID)
constexpr u16 CANFD_OTA_REQ_ID = 0x0100; // OTA 请求基础 ID
constexpr u16 CANFD_OTA_DATA_ID = 0x0101; // OTA 数据基础 ID
constexpr u16 CANFD_OTA_ACK_ID = 0x0102; // OTA 确认基础 ID
constexpr u16 CANFD_OTA_WAIT_ID = 0x0103; // OTA 等待基础 ID
// ADC
constexpr u8 ADC_FILTER_SIZE = 6;
constexpr u8 BLOCK_SIZE = ADC_FILTER_SIZE * SIZE_FLOAT;
constexpr float ERROR_ADC_VAL = 255.0f;
constexpr float MAX_TEMP = 150.0f;
constexpr float MIN_TEMP = -40.0f;
constexpr float MAX_CURRENT = 40.0f;
constexpr float MIN_CURRENT = -40.0f;
constexpr float MAX_VCC = 65.0f;
constexpr float MIN_VCC = -0.1f;
// ang_sensor
constexpr u16 VEL_FILTER_SIZE = 4;
constexpr u16 DEFAULT_COMMAND = 0x0000;
constexpr u16 FAULT_RECEIVE = 0xFFFF;
constexpr float ANGLE_WRAP_THRESHOLD = 300.0f;
constexpr float ANGLE_WRAP_VALUE = 360.0f;
constexpr float RAD_FACTOR = 1.0f / ADC_MAX * 2.0f * PI;
constexpr float ANGLESENS_FACTOR = 1.0f / ADC_MAX * 360.0f;
// TIMER2-任务调度
constexpr int TIMER2_PRESCALER = 119; // 120MHz / 120 = 1MHz
constexpr int TIMER2_PERIOD = 49; // 1 / 1MHz * 50 = 50us
constexpr int MOTOR_PERIOD = 1; // 控制每50us执行一次,无分频
constexpr float TIME_SLICE =
(TIMER2_PERIOD + 1) * (TIMER2_PRESCALER + 1) / 120000000.0f; // 周期
constexpr float TIMER2_FREQUENCY = 1 / TIME_SLICE; // 频率
constexpr float MOTOR_FREQUENCY = 1 / TIME_SLICE / MOTOR_PERIOD; // 频率
// TIMER1-PWM
constexpr int TIMER1_PRESCALER = 0; // 不分频,计数器时钟为 120MHz
constexpr int TIMER1_PERIOD = 2999; // 120MHz / (0+1) / (2999+1) = 40kHz计数, 中心对齐实际PWM 20kHz
constexpr int TIMER1_DEFAULT_PULSE = 0;
constexpr int TIMER1_CH3_COMPARE_VALUE =
(TIMER1_PERIOD + 1) * 0.41 - 1; // PWM 周期 41% 位置触发ADC采样
// 齿槽转矩补偿
constexpr u16 COGGING_TABLE_SIZE = 128; // 每电周期采样点数
constexpr float COGGING_COMP_SCALE = 0.005f; // 补偿换算系数 V/mA,40mA × 0.005 = 0.2V
// 电压检测参数(基于跌幅检测,不依赖固定额定电压)
// 快速检测层(fast_voltage_check,100us周期):
// - 使用峰值检测算法跟踪当前额定电压(vbus_reference)
// - 当电压相对于基准电压下跌超过 VBUS_DROP_THRESHOLD → 关机
// - 当电压低于绝对下限 VBUS_ABSOLUTE_MIN → 关机
// 慢速管理层(power_manage,~10ms周期):
// - 执行Flash保存
// - 状态恢复判断(电压恢复到基准电压的90%以上)
constexpr float VBUS_DROP_THRESHOLD = 5.0f; // 电压跌幅阈值 (V)
constexpr float VBUS_ABSOLUTE_MIN = 12.0f; // 绝对最低电压 (V)
constexpr u32 VBUS_DEBOUNCE_COUNT = 5; // 快速检测:防抖计数 (5次×100us = 500us)
constexpr float VBUS_RECOVERY_RATIO = 0.9f; // 恢复比例(基准电压的90%)
#endif