两轮平衡车控制系统

平衡车控制系统可以理解成:

text 复制代码
一辆天然会倒的车
+
一套实时感知系统
+
一套快速闭环控制算法
+
两个能快速响应的电机

它的核心任务不是"让轮子转",而是:

text 复制代码
车身快倒了 → 让轮子追过去 → 把车身重心重新托住

1. 平衡车控制系统总体目标

平衡车控制系统要解决 4 个问题:

text 复制代码
1. 不倒:车身始终保持接近直立
2. 不乱跑:不要一直往前/往后溜
3. 能运动:可以前进、后退、转弯
4. 要安全:倒地、过流、低电压、传感器异常时立即保护

所以它不是单独一个 PID,而是一个完整系统。


2. 平衡车整体控制框图

最常见的结构是这样的:

text 复制代码
                 遥控/蓝牙/上位机
                       ↓
                 目标速度/目标转向
                       ↓
                速度环 PI 控制
                       ↓
                  目标车身倾角
                       ↓
                角度环 PD 控制
                       ↓
                 电机力矩 / PWM
                       ↓
              左右电机驱动 / FOC
                       ↓
                    轮子运动
                       ↓
                  车身姿态变化
                       ↓
           IMU + 编码器反馈到控制器

更具体一点:

text 复制代码
IMU:测车身角度、角速度
编码器:测轮子速度、位置
电机驱动:控制左右轮输出力矩
控制算法:决定电机该怎么转

3. 平衡车最核心的控制对象是什么?

平衡车主要控制的是 俯仰角 pitch

也就是车身前后倾斜角度。

text 复制代码
车直立:pitch = 0°
车往前倒:pitch > 0° 或 pitch < 0°
车往后倒:pitch < 0° 或 pitch > 0°

具体正负号看你的 IMU 坐标定义。

平衡车真正的控制逻辑是:

text 复制代码
车往前倒 → 轮子往前跑
车往后倒 → 轮子往后跑

这句话非常重要。

如果方向反了,车会越控越倒。


4. 系统硬件组成

1)主控 MCU

如果你打算做 FOC 平衡车,STM32G474 是比较合适的选择。

它主要负责:

text 复制代码
读取 IMU
读取编码器
运行姿态解算
运行 PID/控制算法
输出 PWM/FOC 控制
做保护逻辑
和上位机/蓝牙通信

2)IMU 姿态传感器

IMU 一般包括:

text 复制代码
加速度计
陀螺仪

加速度计可以估计车身倾角,但动态运动时容易被干扰。

陀螺仪可以测角速度,短时间很准,但时间久了会漂移。

所以一般要融合:

text 复制代码
加速度计:长期稳定
陀螺仪:短期灵敏

常见算法:

text 复制代码
互补滤波
Kalman 滤波
Mahony / Madgwick 姿态解算

初学建议先用 互补滤波


3)编码器

编码器用于测左右轮速度。

没有编码器也能让车短时间站住,但是很难做到:

text 复制代码
不溜车
稳定停车
精确前进后退
速度闭环
位置控制

所以平衡车建议必须有编码器。

编码器可以得到:

text 复制代码
左轮速度
右轮速度
平均速度
左右轮速度差
轮子位置

平均速度用于速度环。

左右轮速度差用于转向控制。


4)电机和驱动

平衡车可以用两类电机:

text 复制代码
有刷直流电机 + H 桥驱动
BLDC 无刷电机 + 三相驱动 / FOC

如果你做入门实验,有刷直流电机简单。

如果你想做性能好一点的平衡车,BLDC + FOC 更好。

BLDC FOC 平衡车的控制链路一般是:

text 复制代码
角度环输出力矩需求
↓
转成 iq 电流目标
↓
FOC 电流环控制三相电流
↓
电机输出力矩

FOC 里最关键的是:

text 复制代码
iq 电流 ≈ 电机力矩

所以角度环最后可以输出:

c 复制代码
iq_ref

也就是电机需要多大的力矩。


5. 平衡车控制系统分层设计

推荐分成 5 层:

text 复制代码
第 1 层:底层驱动层
第 2 层:传感器估计层
第 3 层:电机控制层
第 4 层:平衡控制层
第 5 层:状态机和安全保护层

6. 第 1 层:底层驱动层

这一层负责和硬件打交道。

包括:

text 复制代码
IMU I2C/SPI 驱动
编码器定时器输入捕获/正交解码
PWM 输出
ADC 电流采样
电池电压采样
按键/蜂鸣器/LED
串口调试

注意,底层驱动不要和控制算法混在一起。

例如不要在 PID 函数里面直接读 I2C。

建议结构:

c 复制代码
imu_update();
encoder_update();
battery_update();

balance_control();

motor_set_output();

这样层次清楚。


7. 第 2 层:姿态估计层

平衡车需要实时知道车身角度。

IMU 原始数据一般是:

c 复制代码
acc_x, acc_y, acc_z
gyro_x, gyro_y, gyro_z

你需要算出:

c 复制代码
pitch_angle;    // 俯仰角
pitch_gyro;     // 俯仰角速度

简单互补滤波可以这样:

c 复制代码
// 陀螺仪积分得到角度
gyro_angle += gyro_y * dt;

// 加速度计计算倾角
acc_angle = atan2f(acc_x, acc_z) * 57.29578f;

// 互补滤波融合
pitch_angle = 0.98f * (pitch_angle + gyro_y * dt)
            + 0.02f * acc_angle;

这里的 0.980.02 不是绝对的,可以调。

一般理解为:

text 复制代码
98% 相信陀螺仪短期变化
2% 相信加速度计长期校正

8. 第 3 层:电机控制层

如果你用有刷电机,控制输出就是 PWM。

c 复制代码
motor_set_pwm(left_pwm, right_pwm);

如果你用 BLDC FOC,控制输出最好是力矩电流:

c 复制代码
motor_set_iq(left_iq_ref, right_iq_ref);

FOC 系统一般内部还有更快的电流环:

text 复制代码
电流环:10kHz ~ 20kHz
角度环:200Hz ~ 1000Hz
速度环:50Hz ~ 200Hz

如果是 STM32G474 做双电机 FOC,大概结构是:

text 复制代码
ADC 采样三相电流
↓
Clarke 变换
↓
Park 变换
↓
id / iq 电流 PI
↓
反 Park
↓
SVPWM
↓
三相桥

平衡控制器只需要给 FOC 一个:

c 复制代码
iq_ref

也就是力矩目标。


9. 第 4 层:平衡控制层

这是核心。

建议用串级控制:

text 复制代码
速度环 → 角度环 → 电机输出

不要一上来就做很复杂。


9.1 角度环:负责"不倒"

角度环输入:

text 复制代码
目标角度 target_angle
当前角度 pitch_angle
当前角速度 gyro_y

角度环输出:

text 复制代码
电机力矩 / PWM / iq_ref

角度环一般用 PD:

c 复制代码
angle_error = target_angle - pitch_angle;

balance_output = kp_angle * angle_error
               + kd_angle * gyro_y;

这里 gyro_y 前面是加号还是减号,要看你的 IMU 方向和电机方向。

你不要死记公式,要看现象:

text 复制代码
车往前倒,轮子必须往前跑
车往后倒,轮子必须往后跑

角度环的作用:

text 复制代码
车身偏多少,P 负责拉回来
车身倒得多快,D 负责提前抑制

角度环不建议一开始加 I。

因为角度环太敏感,加 I 容易暴冲。


9.2 速度环:负责"不溜车"

只有角度环,车可能能站住,但会慢慢往前或往后跑。

所以需要速度环。

速度环输入:

text 复制代码
目标速度 target_speed
当前速度 current_speed

速度环输出:

text 复制代码
目标倾角 target_angle

这一点非常关键。

速度环不是直接输出 PWM。

速度环输出的是:

text 复制代码
我希望车身往前/往后倾斜多少

例如:

text 复制代码
想往前走 → target_angle = +3°
想往后走 → target_angle = -3°
想停住 → target_angle 接近 0°

速度环代码大概是:

c 复制代码
speed_error = target_speed - current_speed;

speed_integral += speed_error * dt;
speed_integral = limit(speed_integral, -SPEED_I_MAX, SPEED_I_MAX);

target_angle = kp_speed * speed_error
             + ki_speed * speed_integral;

target_angle = limit(target_angle, -8.0f, 8.0f);

速度环一般用 PI。

text 复制代码
P:速度不对,立即修正倾角
I:长期慢慢溜,积分慢慢补回来

9.3 转向环:负责左右转

转向靠左右轮差速。

假设平衡输出是:

c 复制代码
balance_output

转向输出是:

c 复制代码
turn_output

最后左右轮输出:

c 复制代码
left_output  = balance_output - turn_output;
right_output = balance_output + turn_output;

如果用 FOC,就是:

c 复制代码
left_iq_ref  = balance_output - turn_output;
right_iq_ref = balance_output + turn_output;

如果用 PWM,就是:

c 复制代码
left_pwm  = balance_output - turn_output;
right_pwm = balance_output + turn_output;

10. 平衡车推荐控制环结构

完整一点是:

text 复制代码
遥控目标速度 target_speed
        ↓
速度环 PI
        ↓
目标倾角 target_angle
        ↓
角度环 PD
        ↓
平衡输出 balance_output
        ↓
加上转向 turn_output
        ↓
左右电机输出

代码结构:

c 复制代码
void balance_control_loop(void)
{
    float pitch;
    float gyro;
    float left_speed;
    float right_speed;
    float current_speed;

    float speed_error;
    float target_angle;

    float angle_error;
    float balance_output;

    float left_output;
    float right_output;

    // 1. 获取姿态
    pitch = imu_get_pitch_angle();
    gyro  = imu_get_pitch_gyro();

    // 2. 获取轮速
    left_speed  = encoder_get_left_speed();
    right_speed = encoder_get_right_speed();

    // 3. 计算车体平均速度
    current_speed = (left_speed + right_speed) * 0.5f;

    // 4. 速度环:输出目标倾角
    speed_error = target_speed - current_speed;

    speed_integral += speed_error * SPEED_DT;
    speed_integral = limit(speed_integral, -SPEED_I_MAX, SPEED_I_MAX);

    target_angle = KP_SPEED * speed_error
                 + KI_SPEED * speed_integral;

    target_angle = limit(target_angle, -8.0f, 8.0f);

    // 5. 角度环:输出平衡力矩
    angle_error = target_angle - pitch;

    balance_output = KP_ANGLE * angle_error
                   + KD_ANGLE * gyro;

    balance_output = limit(balance_output, -OUTPUT_MAX, OUTPUT_MAX);

    // 6. 转向控制
    turn_output = KP_TURN * target_turn;

    // 7. 左右轮合成
    left_output  = balance_output - turn_output;
    right_output = balance_output + turn_output;

    left_output  = limit(left_output,  -OUTPUT_MAX, OUTPUT_MAX);
    right_output = limit(right_output, -OUTPUT_MAX, OUTPUT_MAX);

    // 8. 倒地保护
    if (pitch > 35.0f || pitch < -35.0f)
    {
        motor_stop();
        speed_integral = 0;
        return;
    }

    // 9. 输出给电机
    motor_set_output(left_output, right_output);
}

11. 控制周期怎么设计?

平衡车对实时性要求很高。

推荐这样设计:

模块 周期 频率
FOC 电流环 50us ~ 100us 10kHz ~ 20kHz
IMU 读取 1ms ~ 5ms 200Hz ~ 1000Hz
姿态解算 1ms ~ 5ms 200Hz ~ 1000Hz
角度环 PD 1ms ~ 5ms 200Hz ~ 1000Hz
速度环 PI 5ms ~ 20ms 50Hz ~ 200Hz
转向控制 5ms ~ 20ms 50Hz ~ 200Hz
电池/温度检测 100ms ~ 500ms 2Hz ~ 10Hz
调试打印 100ms ~ 500ms 2Hz ~ 10Hz

一个比较适合初学者的配置:

text 复制代码
角度环:5ms 一次,200Hz
速度环:10ms 一次,100Hz
调试打印:100ms 一次,10Hz

如果你做 FOC:

text 复制代码
FOC 电流环:20kHz
平衡角度环:500Hz
速度环:100Hz

12. 软件任务设计

如果你裸机写,可以这样:

text 复制代码
定时器中断 1ms:
    设置 1ms 标志位

主循环:
    if 1ms 标志:
        IMU 读取/姿态解算
        角度环计数

    if 5ms 到:
        角度环控制

    if 10ms 到:
        速度环控制

    if 100ms 到:
        电池检测/调试输出

如果你用 RTOS,可以这样:

text 复制代码
高优先级任务:
    FOC / 电机控制 / 角度环

中优先级任务:
    IMU 姿态解算
    编码器速度计算
    速度环

低优先级任务:
    通信
    打印
    参数保存
    LED/蜂鸣器

但是注意:

text 复制代码
不要在高优先级控制环里 printf
不要在控制环里做阻塞 I2C 访问太久
不要让通信任务影响平衡控制任务

13. 状态机设计

平衡车一定要有状态机,不要上电就直接平衡。

推荐状态:

c 复制代码
typedef enum
{
    BALANCE_STATE_INIT = 0,       // 初始化
    BALANCE_STATE_CALIBRATE,      // IMU 零偏校准
    BALANCE_STATE_STANDBY,        // 待机
    BALANCE_STATE_READY,          // 等待扶正
    BALANCE_STATE_RUNNING,        // 平衡运行
    BALANCE_STATE_FALLEN,         // 倒地
    BALANCE_STATE_FAULT           // 故障
} balance_state_t;

流程:

text 复制代码
上电
↓
初始化硬件
↓
IMU 静止校准
↓
检测车身是否接近直立
↓
进入平衡运行
↓
如果角度过大/过流/低电压 → 停机保护

不要一上电就强行输出。

正确做法:

text 复制代码
只有车身角度在 ±10° 以内,才允许进入平衡控制
超过 ±35°,立即停机

14. 安全保护设计

平衡车电机力矩大,必须做保护。

至少要有:

text 复制代码
倒地保护
电机输出限幅
速度限幅
目标角度限幅
积分限幅
电池低压保护
电机过流保护
MOS 过温保护
IMU 异常保护
编码器异常保护
通信丢失保护

例如:

c 复制代码
if (fabsf(pitch_angle) > 35.0f)
{
    motor_stop();
    balance_state = BALANCE_STATE_FALLEN;
}

目标角度也要限幅:

c 复制代码
target_angle = limit(target_angle, -8.0f, 8.0f);

输出限幅:

c 复制代码
motor_output = limit(motor_output, -OUTPUT_MAX, OUTPUT_MAX);

积分限幅:

c 复制代码
speed_integral = limit(speed_integral, -SPEED_I_MAX, SPEED_I_MAX);

15. 调试顺序设计

不要一开始就把所有环都打开。

推荐顺序:

text 复制代码
1. 单独调 IMU
2. 单独调编码器
3. 单独调电机方向
4. 单独调电机闭环速度
5. 确认车身前倾时角度正负
6. 确认输出正值时轮子方向
7. 只开角度 PD
8. 能扶住后再开速度 PI
9. 最后加转向控制
10. 最后做保护和参数保存

第一步:调 IMU

先不要开电机。

串口打印:

text 复制代码
pitch_angle
gyro_y

手动把车往前倾,看:

text 复制代码
pitch_angle 是增大还是减小?
gyro_y 是正还是负?

你要先建立方向概念。


第二步:调电机方向

给固定小 PWM:

c 复制代码
motor_set_output(100, 100);

观察车是往前还是往后。

你要知道:

text 复制代码
output > 0 时,车往哪个方向跑

第三步:确认闭环方向

用手扶着车,轻轻往前倾。

正确现象:

text 复制代码
车往前倾,轮子往前转
车往后倾,轮子往后转

错误现象:

text 复制代码
车往前倾,轮子往后转

如果错误,直接把输出取反:

c 复制代码
balance_output = -balance_output;

或者改电机方向/角度方向。


第四步:只调角度环

先关闭速度环:

c 复制代码
target_angle = 0;

角度环只用 PD:

c 复制代码
balance_output = KP_ANGLE * angle_error
               + KD_ANGLE * gyro;

调参顺序:

text 复制代码
先 Kp
再 Kd
不要先加 Ki

Kp 太小:

text 复制代码
车软,扶不住

Kp 太大:

text 复制代码
前后剧烈抖

Kd 太小:

text 复制代码
来回晃,收不住

Kd 太大:

text 复制代码
电机发麻,高频抖,噪声明显

第五步:再调速度环

角度环能让车有明显回正能力之后,再打开速度环。

速度环输出目标倾角:

c 复制代码
target_angle = speed_PI(target_speed, current_speed);

速度环太弱:

text 复制代码
车能站住,但慢慢溜

速度环太强:

text 复制代码
车一会往前冲,一会往后冲

速度积分太大:

text 复制代码
扶起来突然暴冲

16. 平衡车控制系统里最容易出问题的地方

1)方向错

这是第一大坑。

表现:

text 复制代码
一开控制,车直接加速倒地

解决:

text 复制代码
检查角度方向
检查 gyro 方向
检查电机方向
检查 PID 输出符号

2)控制周期不稳定

表现:

text 复制代码
有时能站,有时突然抖
车身响应不一致

原因可能是:

text 复制代码
控制环里 printf
I2C 读取阻塞太久
任务优先级不合理
中断太多

3)IMU 安装方向不对

IMU 坐标轴必须和车体坐标对应起来。

你需要定义:

text 复制代码
X:车前后方向?
Y:车左右方向?
Z:竖直方向?

否则 pitch/roll 会混乱。


4)机械重心不合理

车身重心太低,响应可能迟钝。

重心太高,容易倒,控制难度大。

一般平衡车重心应该在轮轴上方,不能偏前偏后太多。


5)电机响应太慢

平衡车需要电机快速响应。

如果电机减速箱间隙大、驱动能力弱、死区大,会很难站稳。


17. 推荐你做的最小版本

如果你是初学者,不建议一上来做完整商用品质。

先做最小系统:

text 复制代码
MCU
IMU
两个电机
两个编码器
电机驱动
电池
调试串口

软件先做:

text 复制代码
1. IMU 姿态角
2. 电机正反转
3. 编码器速度
4. 角度 PD
5. 速度 PI
6. 转向差速
7. 安全保护

第一版控制目标不要太高:

text 复制代码
手扶着能回正
松手能站 1~3 秒
能站 10 秒
能基本不溜车
能遥控慢速前进后退
能转向

18. 如果你用 STM32G474 + BLDC FOC,我建议这样设计

控制层级:

text 复制代码
双电机 FOC 电流环:20kHz
↓
左右电机 iq_ref 输入
↓
平衡角度环:500Hz
↓
速度环:100Hz
↓
遥控/通信:20Hz ~ 50Hz

数据流:

text 复制代码
IMU → 姿态解算 → pitch/gyro
编码器 → wheel_speed
速度环 → target_angle
角度环 → balance_iq
转向环 → turn_iq
left_iq  = balance_iq - turn_iq
right_iq = balance_iq + turn_iq
FOC → 三相 PWM

这种结构是比较清晰的。

你可以把平衡控制的输出直接看成:

text 复制代码
我需要多少电机力矩

而 FOC 负责把这个力矩变成实际三相电流。


19. 最终系统结构总结

平衡车控制系统可以总结成:

text 复制代码
传感器层:
    IMU、编码器、电流、电压、温度

估计层:
    姿态角、角速度、轮速、车体速度

控制层:
    速度环 PI
    角度环 PD
    转向差速控制
    FOC 电流环 PI

执行层:
    左右电机驱动
    PWM / SVPWM / iq 电流控制

安全层:
    倒地保护
    过流保护
    低压保护
    传感器异常保护
    通信丢失保护

最核心的一句话是:

text 复制代码
速度环决定车想倾斜多少,
角度环决定电机用多大力把车扶住,
电机驱动负责把这个力真正输出到轮子上。

你真正开始做的时候,不要从完整系统开始。

先把这个最小闭环跑起来:

text 复制代码
IMU 姿态稳定
↓
电机方向正确
↓
角度 PD 能把车扶住
↓
编码器速度环 PI 能防止溜车
↓
最后再做转向和 FOC 优化



两轮自平衡小车 完整控制系统设计分析

一、系统整体设计思路

1. 控制核心原理

本质为倒立摆控制系统 ,车身天然不稳定,依靠传感器实时采集倾角、角速度、电机转速,通过三环串级PID动态调整电机输出力矩,让车轮跟随倾倒方向运动,抵消倾倒趋势实现直立平衡。

2. 整体控制架构

串级闭环控制:速度外环 → 直立内环 ,转向独立差分控制

数据流向:

姿态传感器采集姿态 → 滤波解算倾角 → 速度环修正目标倾角 → 直立环计算主力PWM → 转向环叠加差速PWM → 电机驱动执行

二、系统硬件架构设计

1. 硬件组成清单

模块 选型作用 功能
主控MCU STM32F103C8T6/ESP32 运行PID算法、数据采集、逻辑控制
姿态检测 MPU6050(三轴加速度+三轴陀螺仪) 采集车身倾角、俯仰角速度
测速模块 霍尔编码器直流电机 采集左右轮转速,实现速度闭环
驱动模块 L298N/DRV8833 接收PWM信号驱动电机正反转调速
电源模块 7.4V锂电池 整机供电,稳压供电主控与传感器
辅助外设 蓝牙/遥控按键 人为控制前进后退、转向启停

2. 硬件电路逻辑

  1. MPU6050通过IIC与主控通信,高频读取原始姿态数据
  2. 编码器电机AB相脉冲接入主控外部中断,计数计算实时转速
  3. 主控通用IO输出方向电平,定时器输出PWM波控制电机转速
  4. 电源分压稳压,分开给主控、电机、传感器供电,避免电机大电流干扰姿态数据

三、软件控制系统分层设计

1. 软件整体分层(从上至下)

  1. 应用层:遥控指令处理、状态切换、启停控制
  2. 控制算法层:三环PID控制器、姿态滤波算法
  3. 数据处理层:转速计算、倾角解算、数据校准
  4. 底层驱动层:IIC驱动、定时器PWM、外部中断、电机驱动

2. 核心姿态解算设计

原始MPU6050数据噪声大,无法直接用于PID

采用互补滤波融合加速度计静态倾角+陀螺仪动态角速度

  • 加速度计:静止精准,运动抖动大
  • 陀螺仪:动态响应快,长时间积分漂移
    滤波目的:输出平滑、无漂移、实时可用的车身俯仰倾角,作为PID唯一姿态输入

四、三环PID控制系统详细设计(核心)

设计原则

  1. 内环响应快,外环响应慢
  2. 直立环为核心内环,速度环为稳定外环
  3. 杜绝积分饱和,所有环路增设积分限幅、输出限幅

环1:直立平衡环(内环 PD控制,无积分)

  1. 控制目标:维持车身俯仰角=0°垂直状态
  2. 输入量:滤波后车身倾角、俯仰陀螺仪角速度
  3. 控制方式 :纯PD控制 禁用Ki
  4. 控制公式
    Ubal=Kpbal⋅θ+Kdbal⋅ωU_{bal}=Kp_{bal}\cdot\theta+Kd_{bal}\cdot\omegaUbal=Kpbal⋅θ+Kdbal⋅ω
    θ\thetaθ:倾斜误差角度,ω\omegaω:倾斜角速度
  5. 作用解析
  • P比例项:根据倾斜角度大小输出矫正动力,角度越大矫正力度越强,负责把车扶正
  • D微分项:预判倾倒速度,提前抑制惯性晃动,消除车身高频抖动
  1. 约束设计
    直接限制直立环最终PWM输出幅值,防止满功率暴走

环2:速度稳定环(外环 PI控制,无微分)

  1. 控制目标:平衡车静止不漂移、推动后自动回中位
  2. 输入量:左右电机编码器平均转速
  3. 控制方式 :纯PI控制 禁用Kd
  4. 控制逻辑
    速度环不直接控制电机,输出偏移角度修正值,改变直立环目标倾角,实现前进后退与定点静止
  5. 控制公式
    Espeed=0−VnowE_{speed}=0-V_{now}Espeed=0−Vnow
    Uspeed=Kpspeed⋅Espeed+Kispeed⋅∑EspeedU_{speed}=Kp_{speed}\cdot E_{speed}+Ki_{speed}\cdot\sum E_{speed}Uspeed=Kpspeed⋅Espeed+Kispeed⋅∑Espeed
  6. 关键防积分饱和设计(重中之重)
  • 误差累加值强制限幅,禁止无限累加
  • 速度环输出角度偏移量严格限幅(±10°~±15°),避免倾角过大翻车
  • 车身大幅倾倒时暂停积分,杜绝失控PWM骤增
  1. 功能作用
  • P项:车体发生位移时,快速产生回正牵引力
  • I项:消除静态低速漂移,让小车长期定点站立不溜走

环3:方向转向环(单P差分控制)

  1. 控制目标:实现左右转向、直线行驶纠偏
  2. 输入量:遥控转向指令/车身偏航角速度
  3. 控制方式:单比例P控制
  4. 控制逻辑
    在直立环基础电机PWM上,叠加左右电机差值PWM
    PWMleft=Ubal+UturnPWM_{left}=U_{bal}+U_{turn}PWMleft=Ubal+Uturn
    PWMright=Ubal−UturnPWM_{right}=U_{bal}-U_{turn}PWMright=Ubal−Uturn
  5. 作用:差值调速实现平稳转向,无复杂积分微分,避免转向抖动

五、系统串级控制联动逻辑

  1. 系统初始化:传感器校准、PID参数初始化、电机归零
  2. 周期1~5ms高频循环采集姿态角与电机转速
  3. 优先执行外环速度PI,计算目标倾角偏移量
  4. 将偏移倾角叠加至直立环目标值,执行内环直立PD,算出基础电机PWM
  5. 叠加转向差速PWM,最终限幅后输出至电机驱动
  6. 实时串口打印倾角、转速、PID输出,用于调试观测

六、系统稳定性与抗干扰设计

1. 软件抗干扰

  • 姿态数据多次均值滤波,剔除突发噪声
  • PID运算定时中断执行,固定控制频率,控制节奏稳定
  • 死区处理:极小误差范围内不输出电机动力,避免轻微抖动

2. 硬件抗干扰

  • 电机电源线与传感器信号线分离布线
  • 驱动模块并联续流二极管,吸收电机反向电动势
  • 传感器单独稳压供电,杜绝电机启停电压波动干扰姿态数据

七、系统调试整体流程设计

  1. 底层调试:单独调试电机正反转、PWM调速、编码器测速、姿态倾角输出
  2. 单环调试:关闭速度、转向环,单独调试直立PD,实现小车独立站立
  3. 双环联调:开启速度PI环,调试静止定点、推动回正功能
  4. 整机联调:开启转向环,调试前进后退、左右转向平顺性
  5. 参数精调:优化滤波系数、PID系数,兼顾响应速度与平稳性

八、系统常见问题与控制方案优化

  1. 上电瞬间猛冲失控
    原因:倾角初始校准偏差、PID初始输出过大
    优化:开机延时姿态自校准,上电缓慢提升PID输出
  2. 积分累积导致PWM骤增
    优化:强制积分上下限、输出限幅、倾角过大暂停积分
  3. 站立平稳但行走抖动
    优化:减小直立环Kp,增大D项阻尼,降低速度环响应速度
  4. 静止容易缓慢溜车
    优化:适度增大速度环Ki,强化静差消除能力

九、控制系统整体优缺点分析

优点

  1. 串级PID结构成熟,逻辑清晰,新手易开发调试
  2. 内环高速响应平衡姿态,外环低速稳定位置,控制分层合理
  3. 硬件成本低,代码移植性强,适配绝大多数两轮平衡车
  4. 纯闭环自主平衡,无需人为持续干预

缺点

  1. 依赖姿态传感器精度,数据漂移直接影响平衡效果
  2. 三环参数耦合性较强,参数调试需要一定经验
  3. 高速运动下动态抗冲击能力较弱,仅适用于低速平衡场景

十、整体控制流程图(极简概括)

传感器数据采集 → 滤波解算倾角转速 → 速度环PI修正目标角 → 直立环PD计算主力PWM → 转向环叠加差速 → PWM限幅输出 → 电机执行 → 再次采样闭环循环

需要我把这份设计整理成课程设计报告格式 ,或者直接出完整工程代码+参数整定表吗?

相关推荐
吃好睡好便好2 小时前
Matlab中三种三维图的对比
开发语言·人工智能·学习·算法·matlab·信息可视化
157092511342 小时前
回溯算法基础分享
算法·深度优先
脆皮炸鸡7552 小时前
进程通信----命名管道
linux·经验分享·笔记·算法·学习方法
如竟没有火炬2 小时前
至少有K个重复字符的最长子串
开发语言·数据结构·python·算法·leetcode·动态规划
想带你从多云到转晴2 小时前
优选算法---双指针
java·算法
小O的算法实验室3 小时前
2026年IEEE TSMC,基于Q学习平衡全局与局部搜索的防空资源分配问题进化算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
谙弆悕博士3 小时前
快速学C语言——第17章:多文件编程与头文件规范
c语言·开发语言·算法·学习方法·头文件·多文件编程
水蓝烟雨3 小时前
2359. 找到离给定两个节点最近的节点
算法·leetcode
澈2073 小时前
哈希表:O(1)查找的终极指南
算法·哈希算法·散列表