两轮平衡车PID闭环控制系统
两轮平衡车控制系统,包含直立环(PD)、速度环(PI)、位置环(PID) 的三环闭环控制,支持参数整定、实时监测和仿真测试。
一、系统架构
两轮平衡车控制系统架构:
├── 传感器模块
│ ├── MPU6050陀螺仪加速度计
│ ├── 编码器速度检测
│ └── 超声波/红外位置检测
├── 控制算法模块
│ ├── 直立环PD控制(内环)
│ ├── 速度环PI控制(中环)
│ ├── 位置环PID控制(外环)
│ └── 串级控制融合
├── 电机驱动模块
│ ├── TB6612/TB67H450电机驱动
│ ├── PWM输出控制
│ └── 死区补偿
├── 系统保护模块
│ ├── 倾角超限保护
│ ├── 过流保护
│ └── 欠压保护
└── 调试接口
├── 串口参数配置
├── 实时数据监测
└── 波形显示
二、核心代码实现
2.1 PID控制器结构 (pid_controller.h)
#ifndef PID_CONTROLLER_H
#define PID_CONTROLLER_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
// PID参数结构
typedef struct {
float kp; // 比例系数
float ki; // 积分系数
float kd; // 微分系数
float integral; // 积分项
float prev_error; // 上次误差
float max_output; // 最大输出限制
float min_output; // 最小输出限制
float integral_limit; // 积分限幅
float dead_zone; // 死区
float output; // 当前输出
uint8_t enabled; // 使能标志
} PID_Controller;
// 平衡车系统状态
typedef struct {
// 传感器数据
float pitch; // 俯仰角(度)
float roll; // 横滚角(度)
float gyro_y; // Y轴角速度(度/秒)
float left_speed; // 左轮速度(脉冲/秒)
float right_speed; // 右轮速度(脉冲/秒)
float position; // 位置(米)
// 目标值
float target_pitch; // 目标俯仰角
float target_speed; // 目标速度
float target_position; // 目标位置
// 控制输出
float upright_output; // 直立环输出
float speed_output; // 速度环输出
float position_output; // 位置环输出
float left_motor; // 左电机输出
float right_motor; // 右电机输出
// 系统状态
uint8_t balanced; // 平衡状态
uint8_t moving; // 运动状态
uint8_t error_code; // 错误代码
} BalanceCar_State;
// 系统参数
typedef struct {
// 物理参数
float wheel_radius; // 轮子半径(米)
float car_length; // 车体长度(米)
float mass; // 质量(kg)
float gravity; // 重力加速度
// 编码器参数
int encoder_ppr; // 每转脉冲数
float gear_ratio; // 减速比
// 控制周期
float dt; // 控制周期(秒)
} BalanceCar_Params;
// 函数声明
void PID_Init(PID_Controller *pid, float kp, float ki, float kd);
void PID_SetLimits(PID_Controller *pid, float min, float max);
void PID_SetIntegralLimit(PID_Controller *pid, float limit);
void PID_Enable(PID_Controller *pid, uint8_t enable);
float PID_Calculate(PID_Controller *pid, float target, float feedback);
void PID_Reset(PID_Controller *pid);
// 平衡车控制函数
void BalanceCar_Init(BalanceCar_State *state, BalanceCar_Params *params);
void BalanceCar_UpdateSensors(BalanceCar_State *state,
float pitch, float gyro_y,
int left_encoder, int right_encoder,
float position);
void BalanceCar_ControlLoop(BalanceCar_State *state,
PID_Controller *upright_pid,
PID_Controller *speed_pid,
PID_Controller *position_pid);
void BalanceCar_MotorOutput(BalanceCar_State *state);
void BalanceCar_SafetyCheck(BalanceCar_State *state);
#endif // PID_CONTROLLER_H
2.2 PID控制器实现 (pid_controller.c)
#include "pid_controller.h"
// 初始化PID控制器
void PID_Init(PID_Controller *pid, float kp, float ki, float kd) {
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->integral = 0.0f;
pid->prev_error = 0.0f;
pid->output = 0.0f;
pid->enabled = 1;
pid->dead_zone = 0.0f;
}
// 设置输出限制
void PID_SetLimits(PID_Controller *pid, float min, float max) {
pid->min_output = min;
pid->max_output = max;
}
// 设置积分限制
void PID_SetIntegralLimit(PID_Controller *pid, float limit) {
pid->integral_limit = limit;
}
// 使能/失能PID
void PID_Enable(PID_Controller *pid, uint8_t enable) {
pid->enabled = enable;
if (!enable) {
pid->integral = 0.0f;
pid->prev_error = 0.0f;
}
}
// 计算PID输出
float PID_Calculate(PID_Controller *pid, float target, float feedback) {
if (!pid->enabled) {
return 0.0f;
}
float error = target - feedback;
// 死区处理
if (fabs(error) < pid->dead_zone) {
error = 0.0f;
}
// 比例项
float proportional = pid->kp * error;
// 积分项(抗积分饱和)
pid->integral += pid->ki * error;
if (pid->integral > pid->integral_limit) {
pid->integral = pid->integral_limit;
} else if (pid->integral < -pid->integral_limit) {
pid->integral = -pid->integral_limit;
}
// 微分项(使用微分先行,避免设定值突变)
float derivative = pid->kd * (error - pid->prev_error);
pid->prev_error = error;
// 计算输出
pid->output = proportional + pid->integral + derivative;
// 输出限幅
if (pid->output > pid->max_output) {
pid->output = pid->max_output;
} else if (pid->output < pid->min_output) {
pid->output = pid->min_output;
}
return pid->output;
}
// 重置PID控制器
void PID_Reset(PID_Controller *pid) {
pid->integral = 0.0f;
pid->prev_error = 0.0f;
pid->output = 0.0f;
}
// 更新传感器数据
void BalanceCar_UpdateSensors(BalanceCar_State *state,
float pitch, float gyro_y,
int left_encoder, int right_encoder,
float position) {
state->pitch = pitch;
state->gyro_y = gyro_y;
// 计算速度(脉冲转换为实际速度)
static int prev_left_encoder = 0;
static int prev_right_encoder = 0;
int left_delta = left_encoder - prev_left_encoder;
int right_delta = right_encoder - prev_right_encoder;
// 转换为速度(米/秒)
float dt = 0.005f; // 5ms控制周期
state->left_speed = (float)left_delta / 780.0f * 2.0f * 3.14159f * 0.0325f / dt;
state->right_speed = (float)right_delta / 780.0f * 2.0f * 3.14159f * 0.0325f / dt;
prev_left_encoder = left_encoder;
prev_right_encoder = right_encoder;
state->position = position;
}
// 直立环PD控制(内环)
float Upright_Control(BalanceCar_State *state, PID_Controller *pid) {
// 直立环:角度和角速度反馈
float angle_error = state->target_pitch - state->pitch;
float gyro_feedback = state->gyro_y;
// PD控制
float output = pid->kp * angle_error + pid->kd * gyro_feedback;
// 输出限制
if (output > pid->max_output) output = pid->max_output;
if (output < pid->min_output) output = pid->min_output;
return output;
}
// 速度环PI控制(中环)
float Speed_Control(BalanceCar_State *state, PID_Controller *pid) {
// 计算平均速度
float avg_speed = (state->left_speed + state->right_speed) / 2.0f;
// 速度环输出作为直立环的目标角度
float speed_error = state->target_speed - avg_speed;
// PI控制
pid->integral += pid->ki * speed_error;
if (pid->integral > pid->integral_limit) pid->integral = pid->integral_limit;
if (pid->integral < -pid->integral_limit) pid->integral = -pid->integral_limit;
float output = pid->kp * speed_error + pid->integral;
// 输出限制
if (output > pid->max_output) output = pid->max_output;
if (output < pid->min_output) output = pid->min_output;
return output;
}
// 位置环PID控制(外环)
float Position_Control(BalanceCar_State *state, PID_Controller *pid) {
float position_error = state->target_position - state->position;
// PID控制
pid->integral += pid->ki * position_error;
if (pid->integral > pid->integral_limit) pid->integral = pid->integral_limit;
if (pid->integral < -pid->integral_limit) pid->integral = -pid->integral_limit;
float derivative = pid->kd * (position_error - pid->prev_error);
pid->prev_error = position_error;
float output = pid->kp * position_error + pid->integral + derivative;
// 输出限制
if (output > pid->max_output) output = pid->max_output;
if (output < pid->min_output) output = pid->min_output;
return output;
}
// 主控制循环
void BalanceCar_ControlLoop(BalanceCar_State *state,
PID_Controller *upright_pid,
PID_Controller *speed_pid,
PID_Controller *position_pid) {
// 1. 位置环(外环)
if (position_pid->enabled) {
state->position_output = Position_Control(state, position_pid);
state->target_speed = state->position_output;
}
// 2. 速度环(中环)
if (speed_pid->enabled) {
state->speed_output = Speed_Control(state, speed_pid);
state->target_pitch = state->speed_output;
}
// 3. 直立环(内环)
if (upright_pid->enabled) {
state->upright_output = Upright_Control(state, upright_pid);
}
// 4. 电机输出合成
BalanceCar_MotorOutput(state);
}
// 电机输出计算
void BalanceCar_MotorOutput(BalanceCar_State *state) {
// 直立环输出作为基础
float base_output = state->upright_output;
// 左右轮差速(转向控制)
float turn_diff = 0.0f; // 转向差速,可通过遥控器或陀螺仪获得
// 计算左右电机输出
state->left_motor = base_output - turn_diff;
state->right_motor = base_output + turn_diff;
// 输出限幅
if (state->left_motor > 100.0f) state->left_motor = 100.0f;
if (state->left_motor < -100.0f) state->left_motor = -100.0f;
if (state->right_motor > 100.0f) state->right_motor = 100.0f;
if (state->right_motor < -100.0f) state->right_motor = -100.0f;
}
// 安全检查
void BalanceCar_SafetyCheck(BalanceCar_State *state) {
// 倾角过大保护
if (fabs(state->pitch) > 45.0f) {
state->error_code = 1; // 倾角超限
state->balanced = 0;
state->left_motor = 0;
state->right_motor = 0;
return;
}
// 速度过大保护
float avg_speed = (fabs(state->left_speed) + fabs(state->right_speed)) / 2.0f;
if (avg_speed > 5.0f) { // 5m/s速度限制
state->error_code = 2; // 速度超限
state->balanced = 0;
return;
}
// 正常状态
state->error_code = 0;
state->balanced = 1;
}
2.3 主程序与参数整定 (main.c)
#include "pid_controller.h"
#include <time.h>
#include <unistd.h>
// 系统参数
BalanceCar_Params car_params = {
.wheel_radius = 0.0325f, // 3.25cm轮子半径
.car_length = 0.15f, // 15cm车体长度
.mass = 1.5f, // 1.5kg质量
.gravity = 9.81f, // 重力加速度
.encoder_ppr = 780, // 编码器每转780脉冲
.gear_ratio = 30.0f, // 30:1减速比
.dt = 0.005f // 5ms控制周期
};
// PID控制器
PID_Controller upright_pid; // 直立环
PID_Controller speed_pid; // 速度环
PID_Controller position_pid; // 位置环
// 系统状态
BalanceCar_State car_state;
// 模拟传感器数据
typedef struct {
float pitch;
float gyro_y;
int left_encoder;
int right_encoder;
float position;
} SimulatedData;
SimulatedData sim_data = {0};
// 生成模拟数据
void GenerateSimulatedData(SimulatedData *sim, float target_pitch, float target_speed) {
static float time = 0.0f;
// 模拟倾角变化(受控制输出影响)
sim->pitch += (target_pitch - sim->pitch) * 0.1f + (rand() % 100 - 50) * 0.001f;
// 模拟角速度
sim->gyro_y = (sim->pitch - target_pitch) * 10.0f;
// 模拟编码器
float motor_output = (car_state.left_motor + car_state.right_motor) / 2.0f;
sim->left_encoder += (int)(motor_output * 10.0f);
sim->right_encoder += (int)(motor_output * 10.0f);
// 模拟位置
float avg_speed = motor_output * 0.1f;
sim->position += avg_speed * 0.005f;
time += 0.005f;
}
// 参数整定函数
void AutoTune_Parameters() {
printf("开始参数整定...\n");
// 1. 直立环整定(先关闭速度环和位置环)
printf("1. 直立环整定\n");
PID_Enable(&speed_pid, 0);
PID_Enable(&position_pid, 0);
// 从小到大调整Kp,直到小车能站立但轻微震荡
for (float kp = 10.0f; kp < 100.0f; kp += 5.0f) {
upright_pid.kp = kp;
printf("测试 Kp = %.1f\n", kp);
// 这里应该在实际硬件上测试
usleep(100000); // 模拟延时
}
// 2. 速度环整定
printf("2. 速度环整定\n");
PID_Enable(&speed_pid, 1);
PID_Enable(&position_pid, 0);
// 调整Ki,消除稳态误差
speed_pid.ki = 0.1f;
speed_pid.kp = 5.0f;
// 3. 位置环整定
printf("3. 位置环整定\n");
PID_Enable(&position_pid, 1);
// 标准PID整定
position_pid.kp = 1.0f;
position_pid.ki = 0.05f;
position_pid.kd = 0.1f;
}
// 打印系统状态
void PrintSystemStatus(BalanceCar_State *state) {
static int counter = 0;
if (counter++ % 100 == 0) { // 每500ms打印一次
printf("========================================\n");
printf("俯仰角: %6.2f° 目标: %6.2f°\n", state->pitch, state->target_pitch);
printf("角速度: %6.2f°/s\n", state->gyro_y);
printf("速度: L=%6.2f R=%6.2f m/s\n", state->left_speed, state->right_speed);
printf("位置: %6.2f m 目标: %6.2f m\n", state->position, state->target_position);
printf("输出: L=%6.2f%% R=%6.2f%%\n", state->left_motor, state->right_motor);
printf("直立环: %6.2f 速度环: %6.2f 位置环: %6.2f\n",
state->upright_output, state->speed_output, state->position_output);
printf("状态: %s 错误: %d\n", state->balanced ? "平衡" : "失衡", state->error_code);
printf("========================================\n");
}
}
int main() {
printf("两轮平衡车PID控制系统启动\n");
printf("=============================\n");
// 初始化系统
BalanceCar_Init(&car_state, &car_params);
// 初始化PID参数(经验值)
// 直立环PD参数(最重要)
PID_Init(&upright_pid, 45.0f, 0.0f, 1.2f); // Kp=45, Ki=0, Kd=1.2
PID_SetLimits(&upright_pid, -100.0f, 100.0f);
PID_SetIntegralLimit(&upright_pid, 50.0f);
// 速度环PI参数
PID_Init(&speed_pid, 5.0f, 0.1f, 0.0f); // Kp=5, Ki=0.1, Kd=0
PID_SetLimits(&speed_pid, -10.0f, 10.0f);
PID_SetIntegralLimit(&speed_pid, 5.0f);
// 位置环PID参数
PID_Init(&position_pid, 1.0f, 0.05f, 0.1f); // Kp=1, Ki=0.05, Kd=0.1
PID_SetLimits(&position_pid, -2.0f, 2.0f);
PID_SetIntegralLimit(&position_pid, 1.0f);
// 设置目标值
car_state.target_pitch = 0.0f; // 直立时目标角度为0
car_state.target_speed = 0.0f; // 静止
car_state.target_position = 0.0f; // 原点位置
printf("初始参数设置完成\n");
printf("直立环: Kp=%.1f, Kd=%.1f\n", upright_pid.kp, upright_pid.kd);
printf("速度环: Kp=%.1f, Ki=%.1f\n", speed_pid.kp, speed_pid.ki);
printf("位置环: Kp=%.1f, Ki=%.1f, Kd=%.1f\n", position_pid.kp, position_pid.ki, position_pid.kd);
// 参数整定选项
printf("\n是否进行参数整定?(y/n): ");
char choice;
scanf(" %c", &choice);
if (choice == 'y' || choice == 'Y') {
AutoTune_Parameters();
}
printf("\n开始控制循环...\n");
// 控制循环
int step = 0;
while (1) {
// 生成模拟传感器数据
GenerateSimulatedData(&sim_data, car_state.target_pitch, car_state.target_speed);
// 更新传感器数据
BalanceCar_UpdateSensors(&car_state,
sim_data.pitch,
sim_data.gyro_y,
sim_data.left_encoder,
sim_data.right_encoder,
sim_data.position);
// 安全检查
BalanceCar_SafetyCheck(&car_state);
if (car_state.balanced) {
// 执行控制循环
BalanceCar_ControlLoop(&car_state, &upright_pid, &speed_pid, &position_pid);
}
// 打印系统状态
PrintSystemStatus(&car_state);
// 模拟控制周期
usleep(5000); // 5ms
// 测试不同工况
step++;
if (step == 1000) { // 5秒后前进
printf("\n>>> 开始前进测试 <<<\n");
car_state.target_speed = 0.5f; // 0.5m/s
} else if (step == 2000) { // 10秒后后退
printf("\n>>> 开始后退测试 <<<\n");
car_state.target_speed = -0.5f; // -0.5m/s
} else if (step == 3000) { // 15秒后位置控制
printf("\n>>> 开始位置控制测试 <<<\n");
car_state.target_position = 2.0f; // 前进2米
} else if (step == 4000) { // 20秒后停止
printf("\n>>> 停止测试 <<<\n");
car_state.target_speed = 0.0f;
car_state.target_position = 0.0f;
}
}
return 0;
}
2.4 硬件接口层 (hardware_interface.h)
#ifndef HARDWARE_INTERFACE_H
#define HARDWARE_INTERFACE_H
#include "pid_controller.h"
// 硬件接口函数声明
void HW_Init(void);
void HW_Encoder_Init(void);
void HW_MPU6050_Init(void);
void HW_Motor_Init(void);
void HW_Ultrasonic_Init(void);
// 读取传感器数据
float HW_ReadPitch(void);
float HW_ReadGyroY(void);
int HW_ReadLeftEncoder(void);
int HW_ReadRightEncoder(void);
float HW_ReadPosition(void);
// 设置电机输出
void HW_SetMotorOutput(float left, float right);
// 系统保护
void HW_OverCurrentProtection(void);
void HW_TiltProtection(void);
void HW_UnderVoltageProtection(void);
// 调试接口
void HW_DebugPrint(const char *format, ...);
void HW_SendDataToPC(BalanceCar_State *state);
#endif // HARDWARE_INTERFACE_H
2.5 参数配置文件 (config.h)
#ifndef CONFIG_H
#define CONFIG_H
// 系统配置参数
#define CONTROL_PERIOD_MS 5 // 控制周期5ms
#define ENCODER_PPR 780 // 编码器每转脉冲数
#define WHEEL_RADIUS_MM 32.5 // 轮子半径32.5mm
#define CAR_LENGTH_MM 150.0 // 车体长度150mm
#define MAX_TILT_ANGLE 45.0 // 最大倾角45度
#define MAX_SPEED_MS 5.0 // 最大速度5m/s
// PID参数默认值
#define UPRIGHT_KP_DEFAULT 45.0f
#define UPRIGHT_KI_DEFAULT 0.0f
#define UPRIGHT_KD_DEFAULT 1.2f
#define SPEED_KP_DEFAULT 5.0f
#define SPEED_KI_DEFAULT 0.1f
#define SPEED_KD_DEFAULT 0.0f
#define POSITION_KP_DEFAULT 1.0f
#define POSITION_KI_DEFAULT 0.05f
#define POSITION_KD_DEFAULT 0.1f
// 电机参数
#define MOTOR_PWM_MAX 1000
#define MOTOR_DEAD_ZONE 50
#define MOTOR_ACCEL_LIMIT 100
// 调试选项
#define DEBUG_ENABLED 1
#define DATA_RECORD_ENABLED 1
#define PLOT_ENABLED 1
#endif // CONFIG_H
三、编译与部署
3.1 Makefile
# 两轮平衡车PID控制系统 Makefile
CC = arm-none-eabi-gcc
CFLAGS = -Wall -Wextra -O2 -std=c99 -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard
LDFLAGS = -Tstm32f407.ld -Wl,-Map=output.map
# 源文件
SRCS = main.c pid_controller.c hardware_interface.c
OBJS = $(SRCS:.c=.o)
# 目标文件
TARGET = balance_car
all: $(TARGET).elf $(TARGET).bin
$(TARGET).elf: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
$(TARGET).bin: $(TARGET).elf
arm-none-eabi-objcopy -O binary $< $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o *.elf *.bin *.map
flash: $(TARGET).bin
st-flash write $< 0x08000000
.PHONY: all clean flash
3.2 实时数据监测脚本 (monitor.py)
#!/usr/bin/env python3
import serial
import matplotlib.pyplot as plt
import numpy as np
from collections import deque
import threading
class BalanceCarMonitor:
def __init__(self, port='/dev/ttyUSB0', baudrate=115200):
self.ser = serial.Serial(port, baudrate, timeout=1)
self.data_queue = deque(maxlen=1000)
self.running = False
def start(self):
self.running = True
thread = threading.Thread(target=self.read_serial)
thread.daemon = True
thread.start()
self.plot_data()
def read_serial(self):
while self.running:
try:
line = self.ser.readline().decode('utf-8').strip()
if line.startswith('='):
# 解析数据
parts = line.split()
if len(parts) >= 10:
data = {
'pitch': float(parts[1]),
'target_pitch': float(parts[3]),
'gyro': float(parts[5]),
'left_speed': float(parts[7]),
'right_speed': float(parts[9]),
'position': float(parts[11])
}
self.data_queue.append(data)
except:
pass
def plot_data(self):
plt.ion()
fig, axes = plt.subplots(3, 2, figsize=(12, 8))
while self.running:
if len(self.data_queue) > 10:
# 提取数据
pitches = [d['pitch'] for d in list(self.data_queue)[-100:]]
targets = [d['target_pitch'] for d in list(self.data_queue)[-100:]]
positions = [d['position'] for d in list(self.data_queue)[-100:]]
speeds = [(d['left_speed'] + d['right_speed'])/2 for d in list(self.data_queue)[-100:]]
# 清除并重新绘制
for ax in axes.flat:
ax.clear()
# 倾角图
axes[0,0].plot(pitches, 'b-', label='实际倾角')
axes[0,0].plot(targets, 'r--', label='目标倾角')
axes[0,0].set_title('倾角控制')
axes[0,0].set_ylabel('角度(°)')
axes[0,0].legend()
axes[0,0].grid(True)
# 位置图
axes[0,1].plot(positions, 'g-', label='实际位置')
axes[0,1].set_title('位置控制')
axes[0,1].set_ylabel('位置(m)')
axes[0,1].legend()
axes[0,1].grid(True)
# 速度图
axes[1,0].plot(speeds, 'm-', label='实际速度')
axes[1,0].set_title('速度控制')
axes[1,0].set_ylabel('速度(m/s)')
axes[1,0].legend()
axes[1,0].grid(True)
# PID输出
axes[1,1].plot([d['pitch'] for d in list(self.data_queue)[-100:]], 'c-', label='直立环输出')
axes[1,1].set_title('PID输出')
axes[1,1].set_ylabel('输出(%)')
axes[1,1].legend()
axes[1,1].grid(True)
# 误差图
errors = [t - p for t, p in zip(targets, pitches)]
axes[2,0].plot(errors, 'r-', label='倾角误差')
axes[2,0].set_title('控制误差')
axes[2,0].set_ylabel('误差(°)')
axes[2,0].legend()
axes[2,0].grid(True)
# 状态图
axes[2,1].plot([1]*len(pitches), 'k-', alpha=0.3)
axes[2,1].fill_between(range(len(pitches)), pitches, targets, alpha=0.3, color='red')
axes[2,1].set_title('控制状态')
axes[2,1].set_ylabel('状态')
axes[2,1].grid(True)
plt.tight_layout()
plt.pause(0.1)
plt.pause(0.1)
def stop(self):
self.running = False
self.ser.close()
if __name__ == '__main__':
monitor = BalanceCarMonitor()
try:
monitor.start()
except KeyboardInterrupt:
monitor.stop()
参考代码 包括速度环和位置环的pid闭环控制对两轮车的平衡进行调节 www.youwenfan.com/contentcnv/72184.html
四、参数整定指南
4.1 整定步骤
-
直立环整定(最关键)
- 关闭速度环和位置环
- 只保留直立环PD控制
- 从小到大调整Kp,直到小车能站立但不稳
- 增加Kd,减小震荡
-
速度环整定
- 开启直立环和速度环
- 设置小目标速度(0.2m/s)
- 调整Kp消除稳态误差
- 调整Ki消除静差
-
位置环整定
- 开启所有环路
- 设置小目标位置(0.5m)
- 标准PID整定
4.2 典型参数范围
| 参数 | 范围 | 说明 |
|---|---|---|
| 直立环Kp | 30-80 | 越大响应越快,但易震荡 |
| 直立环Kd | 0.5-3.0 | 抑制震荡,过大产生高频噪声 |
| 速度环Kp | 3-10 | 影响速度响应 |
| 速度环Ki | 0.05-0.5 | 消除稳态误差 |
| 位置环Kp | 0.5-3.0 | 影响位置精度 |
| 位置环Ki | 0.01-0.1 | 消除位置静差 |
| 位置环Kd | 0.05-0.5 | 抑制位置超调 |
五、故障排除
5.1 常见问题
-
无法站立
- 检查倾角传感器安装方向
- 检查电机极性
- 调整直立环Kp
-
前后晃动
- 增加直立环Kd
- 减小直立环Kp
- 检查机械结构松动
-
漂移严重
- 调整速度环Ki
- 检查编码器安装
- 校准传感器零点
-
响应迟钝
- 增大直立环Kp
- 减小速度环Ki
- 检查控制周期