力位混合控制库使用指南

力位混合控制库使用指南

SDK Ver.V1.11.0

概述

力位混合控制(Hybrid Force-Position Control)是一种结合力控制和位置控制的阻抗控制方法,广泛应用于机器人关节控制、柔顺装配、人机交互等场景。本库实现了基于PD+前馈的阻抗控制算法,集成于HPM MCL电机控制库中。

控制原理

阻抗控制模型

力位混合控制的核心思想是让关节表现出期望的机械阻抗特性,即弹簧-阻尼系统特性。控制律如下:

\tau = \tau_{ff} + k_p (q_{des} - q) + k_d (\dot{q}_{des} - \dot{q})

其中:

  • \tau 为输出力矩 (N·m)
  • \tau_{ff} 为前馈力矩,用于重力补偿等 (N·m)
  • k_p 为位置刚度增益 (N·m/rad)
  • k_d 为阻尼增益 (N·m·s/rad)
  • q_{des} 为期望位置 (rad)
  • q 为实际位置 (rad)
  • \dot{q}_{des} 为期望速度 (rad/s),位置保持时通常为0
  • \dot{q} 为实际速度 (rad/s)

物理意义

该控制律模拟了一个虚拟的弹簧-阻尼系统:

\tau = k_p \cdot e_p + k_d \cdot e_v
  • 位置刚度 k_p:决定关节对位置偏差的恢复力,类似弹簧刚度
  • 阻尼系数 k_d:决定关节对速度的阻尼力,抑制振荡

临界阻尼条件

为获得无超调的快速响应,通常采用临界阻尼设计:

k_d = 2\sqrt{k_p \cdot J}

其中 J 为关节等效转动惯量。对于未知惯量的系统,可简化为:

k_d \approx 2\sqrt{k_p}

系统架构

力位混合控制作为位置/力外环,输出力矩指令给FOC电流内环:

力位混合控制 (20kHz) → 力矩指令τ → 力矩常数kt转换 → q轴电流iq → FOC电流环 → PWM

力矩到电流的转换公式:

i_q = \frac{\tau}{k_t}

其中 k_t 为电机转矩常数 (N·m/A)。

API说明

数据结构

配置结构体

typedef struct {
    float kp;               /* 位置刚度 (N·m/rad) */
    float kd;               /* 阻尼系数 (N·m·s/rad) */
    float tau_ff;           /* 前馈力矩 (N·m) */
    float q_des;            /* 期望位置 (rad) */
    float dq_des;           /* 期望速度 (rad/s) */
    float tau_max;          /* 最大输出力矩 (N·m) */
    float tau_min;          /* 最小输出力矩 (N·m) */
    float speed_lpf_alpha;  /* 速度低通滤波系数 (0-1) */
    float speed_deadzone;   /* 速度死区 (rad/s) */
} mcl_hybrid_ctrl_cfg_t;

状态结构体

typedef struct {
    float q_actual;     /* 实际位置 (rad) - 输入 */
    float dq_actual;    /* 实际速度 (rad/s) - 输入 */
    float tau_output;   /* 输出力矩 (N·m) - 输出 */
    float pos_error;    /* 位置误差 (rad) - 输出 */
    float vel_error;    /* 速度误差 (rad/s) - 输出 */
    float speed_lpf;    /* 滤波后速度 (rad/s) - 内部 */
} mcl_hybrid_ctrl_state_t;

核心函数

函数 说明
mcl_hybrid_ctrl_init() 初始化配置,所有参数置零
mcl_hybrid_ctrl_step() 执行一次控制计算
mcl_hybrid_ctrl_set_kp() 设置位置刚度
mcl_hybrid_ctrl_set_kd() 设置阻尼系数
mcl_hybrid_ctrl_set_position() 设置期望位置
mcl_hybrid_ctrl_set_velocity() 设置期望速度
mcl_hybrid_ctrl_set_limits() 设置力矩限幅
mcl_hybrid_ctrl_set_speed_filter() 设置速度滤波参数

使用示例

参数初始化

以下为 bldc_foc 示例中的初始化代码,适用于空载直驱电机:

void motor0_hybrid_ctrl_init(void)
{
    /* 初始化配置结构体 */
    mcl_hybrid_ctrl_init(&motor0.hybrid_ctrl_cfg);
    /* 清零状态结构体 */
    memset(&motor0.hybrid_ctrl_state, 0, sizeof(motor0.hybrid_ctrl_state));

    /* 设置PD参数 - 空载直驱电机参数较小 */
    mcl_hybrid_ctrl_set_kp(&motor0.hybrid_ctrl_cfg, 0.06f);
    mcl_hybrid_ctrl_set_kd(&motor0.hybrid_ctrl_cfg, 0.001429f);

    /* 设置初始期望位置和速度 */
    mcl_hybrid_ctrl_set_position(&motor0.hybrid_ctrl_cfg, 0.0f);
    mcl_hybrid_ctrl_set_velocity(&motor0.hybrid_ctrl_cfg, 0.0f);

    /* 设置力矩限幅,防止过流 */
    mcl_hybrid_ctrl_set_limits(&motor0.hybrid_ctrl_cfg, -0.5f, 0.5f);

    /* 设置速度滤波:alpha=0.003(强滤波),死区=0.1 rad/s */
    mcl_hybrid_ctrl_set_speed_filter(&motor0.hybrid_ctrl_cfg, 0.003f, 0.1f);
}

控制循环

在ADC中断(PWM周期触发,20kHz)中执行控制算法:

void isr_adc(void)
{
    uint32_t status;
    mcl_user_value_t user_current;

    status = hpm_adc_get_status_flags(&hpm_adc_u);
    if ((status & BOARD_BLDC_ADC_TRIG_FLAG) != 0) {
        hpm_adc_clear_status_flags(&hpm_adc_u, BOARD_BLDC_ADC_TRIG_FLAG);

        /* 编码器数据处理 */
        hpm_mcl_encoder_process(&motor0.encoder,
            motor0.cfg.mcl.physical.time.mcu_clock_tick / PWM_FREQUENCY);

        if (hybrid_ctrl_mode) {
            /* 步骤1:获取编码器反馈 */
            hpm_mcl_encoder_get_absolute_theta(&motor0.encoder,
                &motor0.hybrid_ctrl_state.q_actual);
            motor0.hybrid_ctrl_state.dq_actual =
                hpm_mcl_encoder_get_speed(&motor0.encoder);

            /* 步骤2:执行力位混合控制算法 */
            mcl_hybrid_ctrl_step(&motor0.hybrid_ctrl_cfg,
                &motor0.hybrid_ctrl_state);

            /* 步骤3:力矩转电流,发送给FOC电流环 */
            user_current.enable = true;
            /* kt = 0.053 N·m/A(电机转矩常数) */
            user_current.value = motor0.hybrid_ctrl_state.tau_output / 0.053f;
            hpm_mcl_loop_set_current_q(&motor0.loop, user_current);
        }

        /* 执行FOC电流环 */
        hpm_mcl_loop(&motor0.loop);
    }
}

用户交互

主循环中的模式选择和位置输入:

if (user_mode == 2) {
    /* 初始化力位混合控制 */
    motor0_hybrid_ctrl_init();
    hybrid_ctrl_mode = true;

    /* 禁用速度环,由力位混合控制接管 */
    user_speed.enable = false;
    hpm_mcl_loop_set_speed(&motor0.loop, user_speed);

    printf("\r\nHybrid control mode\r\n");
    printf("kp=%.3f, kd=%.3f, tau_limit=%.3f\r\n",
           (double)motor0.hybrid_ctrl_cfg.kp,
           (double)motor0.hybrid_ctrl_cfg.kd,
           (double)motor0.hybrid_ctrl_cfg.tau_max);

    while (1) {
        /* 读取用户输入的目标位置(度) */
        position = atoi(input_data);

        /* 角度转弧度:deg * (π/180) ≈ deg * 0.01745 */
        mcl_hybrid_ctrl_set_position(&motor0.hybrid_ctrl_cfg,
            (float)position * 0.00157079632f);  /* 实际为 deg * π/180 / 10 */

        printf("Pos: %d deg, Tau: %.4f Nm, Pos_err: %.4f rad\r\n",
               position,
               (double)motor0.hybrid_ctrl_state.tau_output,
               (double)motor0.hybrid_ctrl_state.pos_error);
    }
}

参数调节指南

参数含义与调节

位置刚度 kp

位置刚度决定了关节对位置偏差产生的恢复力矩:

\tau_p = k_p \cdot (q_{des} - q)
kp范围 特性 应用场景
0.01-0.1 非常柔顺 空载直驱电机测试
0.1-1.0 柔顺 小型关节、人机交互
1.0-10 中等刚度 带减速器的关节
10-100 刚性 工业伺服定位
100-500 非常刚性 高精度定位

阻尼系数 kd

阻尼系数决定了关节对速度的阻尼力矩:

\tau_d = k_d \cdot (\dot{q}_{des} - \dot{q})

推荐按临界阻尼设计:

k_d = 2\sqrt{k_p}
现象 原因 调节方法
振荡/超调 kd过小 增大kd
响应迟缓 kd过大 减小kd
抖动 速度噪声 增加速度滤波

力矩限幅

保护电机和驱动器,防止过流:

\tau_{min} \leq \tau_{output} \leq \tau_{max}

根据电机额定电流和转矩常数计算最大力矩:

\tau_{max} = k_t \cdot I_{max}

速度滤波

速度信号通常噪声较大,建议使用低通滤波:

\dot{q}_{filtered}[n] = \alpha \cdot \dot{q}[n] + (1-\alpha) \cdot \dot{q}_{filtered}[n-1]
  • \alpha 越小,滤波越强(推荐0.003-0.1)
  • 死区用于消除静止时的小幅抖动

不同应用场景的参数配置

空载直驱电机(测试用)

mcl_hybrid_ctrl_set_kp(&cfg, 0.06f);
mcl_hybrid_ctrl_set_kd(&cfg, 0.001429f);
mcl_hybrid_ctrl_set_limits(&cfg, -0.5f, 0.5f);
mcl_hybrid_ctrl_set_speed_filter(&cfg, 0.003f, 0.1f);

特点:惯量小,无减速器,参数需要较小以避免过激响应。

带减速器的关节电机

假设减速比 N=100,电机端转矩常数 k_t=0.1 N·m/A,最大电流3A:

/* 输出端等效刚度 = 电机端刚度 × 减速比² */
mcl_hybrid_ctrl_set_kp(&cfg, 50.0f);
mcl_hybrid_ctrl_set_kd(&cfg, 14.0f);  /* ≈ 2*sqrt(50) */
/* 输出端最大力矩 = 电机端力矩 × 减速比 */
mcl_hybrid_ctrl_set_limits(&cfg, -30.0f, 30.0f);  /* 0.1 × 3 × 100 */
mcl_hybrid_ctrl_set_speed_filter(&cfg, 0.05f, 0.01f);

柔顺人机交互

需要较低刚度,允许人手推动:

mcl_hybrid_ctrl_set_kp(&cfg, 5.0f);
mcl_hybrid_ctrl_set_kd(&cfg, 4.5f);  /* ≈ 2*sqrt(5) */
mcl_hybrid_ctrl_set_limits(&cfg, -5.0f, 5.0f);

高精度定位

需要较高刚度和强阻尼:

mcl_hybrid_ctrl_set_kp(&cfg, 200.0f);
mcl_hybrid_ctrl_set_kd(&cfg, 28.0f);  /* ≈ 2*sqrt(200) */
mcl_hybrid_ctrl_set_limits(&cfg, -50.0f, 50.0f);

参数整定步骤

  1. 确定力矩限幅:根据电机额定电流和转矩常数计算
  2. 设置初始kp:从较小值开始(如1.0)
  3. 设置kd为临界阻尼k_d = 2\sqrt{k_p}
  4. 测试响应
    • 振荡 → 增大kd
    • 太慢 → 增大kp(同时调整kd)
    • 抖动 → 减小速度滤波系数alpha
  5. 逐步增大kp:直到达到期望的刚度

注意事项

  1. 电机转矩常数:需要根据实际电机参数设置,可从电机规格书获取或通过标定测量
  2. 编码器精度:位置和速度反馈精度直接影响控制效果
  3. 安全限幅:务必设置合理的力矩限幅,防止失控
0
0

订阅

发表回复 0

Your email address will not be published. Required fields are marked *

captcha
Enter the characters shown in the image:
Reload

This CAPTCHA helps ensure that you are human. Please enter the requested characters.