【花雕学编程】Arduino PID 之机器人平衡控制

在这里插入图片描述

Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用Arduino IDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Arduino的功能和学习Arduino的知识。

Arduino的特点是:
1、开放源码:Arduino的硬件和软件都是开放源码的,你可以自由地修改、复制和分享它们。
2、易用:Arduino的硬件和软件都是为初学者和非专业人士设计的,你可以轻松地上手和使用它们。
3、便宜:Arduino的硬件和软件都是非常经济的,你可以用很低的成本来实现你的想法。
4、多样:Arduino有多种型号和版本,你可以根据你的需要和喜好来选择合适的Arduino板。
5、创新:Arduino可以让你用电子的方式来表达你的创意和想象,你可以用Arduino来制作各种有趣和有用的项目,如机器人、智能家居、艺术装置等。

在这里插入图片描述
在 Arduino 系统中,PID 算法主要用于对各种物理量(如温度、速度、位置等)进行精确控制。例如,通过连接温度传感器到 Arduino,利用 PID 算法可以精准控制加热或制冷设备,使温度稳定在设定值;在电机控制中,PID 可以根据目标速度和实际速度的偏差来调整电机的驱动信号,实现稳定的转速控制。

主要特点
1、实时反馈控制:PID控制器能够实时处理系统误差,通过比例、积分和微分三部分的调节,快速响应外部扰动,保持系统的稳定性。
2、简单易用:PID控制算法相对简单,易于实现和调试,适合大多数嵌入式系统和实时控制应用。
3、适应性强:PID控制器可以根据系统的动态特性进行调整,适应不同的负载和工作条件,保持良好的控制效果。
4、高精度控制:PID控制能够快速且准确地调整电机速度,确保电机在各种工况下都能稳定地达到设定速度,减少稳态误差。
5、良好的动态响应:通过调整比例、积分和微分参数,控制系统能够快速响应速度变化,适应负载变化和外部扰动,保持系统的稳定性。

应用场景
1、机器人运动控制:在机器人技术中,基于速度闭环的PID控制可以用于电机的速度调节,实现精确的运动控制,提高机器人的灵活性和稳定性。
2、自动化生产线:在自动化设备中,如传送带和机械手臂,PID控制能够确保各个设备的速度稳定,提高生产效率和产品质量。
3、电动工具:在电动工具(如电钻、切割机等)中,PID控制可以实现对电机转速的精确调节,满足不同工作条件的需要。
4、风扇和泵控制:在风扇和水泵等设备中,PID控制能够根据需求自动调节转速,提供适合的流量和风速,提高系统的能效。
5、电动车辆:在电动交通工具中,速度闭环PID控制可以用于电机的速度调节,提升驾驶的平顺性和安全性。

需要注意的事项
1、参数调试:PID控制器的效果高度依赖于参数设置,开发者需要进行细致的调试,以防止系统震荡或响应不及时。
2、传感器校准:使用PID控制时,需要定期校准传感器,以确保数据准确性,特别是在不同的环境条件下使用时。
3、数据融合:在控制中,可以考虑使用数据融合算法(如互补滤波或卡尔曼滤波)来提高姿态估计的稳定性和准确性。
4、电源管理:确保电源供应稳定且符合电机的工作要求,以避免电压波动对电机驱动性能造成影响。
5、热管理:设计合适的散热方案,以防止电机和驱动器过热,影响系统性能和寿命。

在这里插入图片描述

主要特点

  1. 精确的反馈调节
    PID(比例 - 积分 - 微分)控制器依据传感器反馈的信息,如陀螺仪、加速度计测量的角度和角速度,精确计算出机器人与期望平衡状态的偏差。通过比例(P)环节对当前偏差做出快速响应,积分(I)环节消除系统的稳态误差,微分(D)环节预测偏差的变化趋势并提前进行调整。这种综合的反馈调节机制能让机器人迅速且精准地调整姿态,保持平衡。
  2. 实时动态响应
    机器人在运动过程中,平衡状态时刻受到各种因素的影响,如地面不平、外力干扰等。PID 控制器能够实时监测这些变化,并在短时间内做出响应,动态调整控制输出,使机器人始终保持平衡。它可以根据不同的情况快速调整电机的转速和扭矩,确保机器人在复杂环境下稳定运行。
  3. 适应性强
    PID 控制器可以通过调整比例、积分、微分三个参数来适应不同类型的机器人和工作环境。不同结构、重量和运动特性的机器人,其平衡控制的需求也不同。通过合理设置 PID 参数,能够使控制器在各种条件下都能实现良好的平衡控制效果。例如,对于双足机器人和轮式机器人,可根据其特点分别优化 PID 参数。
  4. 易于实现与集成
    在 Arduino 平台上实现 PID 控制算法相对简单。Arduino 具有丰富的接口和开源的开发环境,方便连接各种传感器和执行器,如电机驱动器。开发者可以利用现有的库函数和代码模板,快速搭建起机器人的平衡控制系统,将 PID 算法集成到整个系统中。

应用场景

  1. 双足机器人
    双足机器人在行走过程中需要不断调整自身姿态以保持平衡。PID 控制器可以根据传感器反馈的身体倾斜角度和角速度,实时调整腿部关节的运动,使机器人能够稳定地站立和行走。这在机器人竞赛、服务机器人等领域有着广泛的应用,如机器人舞蹈表演、家庭服务机器人的自主移动等。
  2. 倒立摆机器人
    倒立摆是一个经典的控制问题,机器人需要通过控制底部的移动平台,使摆杆保持垂直平衡状态。PID 控制器能够根据摆杆的倾斜角度和角速度,精确控制平台的运动,实现倒立摆的稳定平衡。这种控制技术在教学实验、科研以及一些工业自动化中的平衡控制问题上有重要的应用。
  3. 两轮自平衡机器人
    两轮自平衡机器人依靠两个轮子支撑并保持平衡,通过改变轮子的转速来实现前进、后退和转弯。PID 控制器可以根据机器人的倾斜角度和速度,实时调整两个轮子的转速差,使机器人在各种路况下都能保持稳定的平衡状态。这类机器人常用于个人交通工具、巡检机器人等领域。
  4. 工业搬运机器人
    在工业生产中,一些搬运机器人需要在移动过程中保持货物的平衡和稳定。PID 控制器可以帮助机器人根据负载的变化和运动状态,调整自身的姿态和运动方式,确保货物安全地搬运到指定位置,提高生产效率和质量。

需要注意的事项

  1. PID 参数整定
    PID 参数的选择直接影响机器人的平衡控制效果。不合适的参数可能导致机器人出现振荡、响应迟缓或无法保持平衡等问题。整定 PID 参数通常需要进行多次实验和调试,可采用试错法、Ziegler - Nichols 方法等。在调试过程中,要充分考虑机器人的动态特性、传感器的精度和噪声等因素。
  2. 传感器精度与噪声处理
    传感器的精度和可靠性对平衡控制至关重要。陀螺仪、加速度计等传感器可能存在测量误差和噪声,会影响 PID 控制器的计算结果。因此,需要对传感器进行校准和滤波处理,如采用卡尔曼滤波、互补滤波等算法,提高传感器数据的准确性和稳定性。
  3. 执行器响应速度
    执行器(如电机)的响应速度会影响机器人的平衡控制性能。如果执行器的响应速度过慢,无法及时跟随 PID 控制器的输出信号,机器人可能会失去平衡。在选择执行器时,要考虑其扭矩、转速和响应时间等参数,确保其能够满足机器人平衡控制的要求。
  4. 系统稳定性与抗干扰能力
    机器人在实际运行中会受到各种外界干扰,如地面震动、风力等。在设计 PID 控制器时,要考虑系统的稳定性和抗干扰能力。可以通过增加积分饱和限制、引入自适应控制等方法,提高系统在复杂环境下的稳定性和抗干扰能力。
  5. 硬件资源限制
    Arduino 的硬件资源有限,如处理器速度、内存容量等。在实现 PID 控制算法时,要充分考虑这些限制,优化代码结构,减少不必要的计算和内存占用。同时,要注意传感器和执行器的通信速率,避免因数据传输延迟影响平衡控制效果。

在这里插入图片描述

1、两轮自平衡机器人
硬件配置
Arduino Uno主控板
MPU6050陀螺仪+加速度计
L298N电机驱动模块
直流减速电机(带编码器)
代码实现

#include <Wire.h>
#include <MPU6050.h>
 
MPU6050 mpu;
float Kp=30, Ki=0.5, Kd=2;
float angle, angleSetPoint=0, error, lastError, integral, derivative;
int motorSpeed=0;
 
void setup() {
    
    
  Wire.begin();
  mpu.initialize();
  Serial.begin(9600);
}
 
void loop() {
    
    
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  angle = 0.98 * (angle + (gx/131.0)*0.01) + 0.02 * atan2(ay, az) * 57.296;
 
  error = angleSetPoint - angle;
  integral += error * 0.01;
  derivative = (error - lastError) / 0.01;
  motorSpeed = Kp*error + Ki*integral + Kd*derivative;
 
  if (motorSpeed > 255) motorSpeed = 255;
  else if (motorSpeed < -255) motorSpeed = -255;
 
  analogWrite(9, abs(motorSpeed));
  digitalWrite(8, motorSpeed > 0 ? HIGH : LOW);
 
  lastError = error;
  delay(10);
}

技术要点
互补滤波:融合陀螺仪角速度与加速度计角度,消除漂移
编码器反馈:通过PWM占空比调整电机转速,实现速度闭环控制
防积分饱和:积分项最大值限制在±50范围内
物理约束:限制电机PWM输出在±255,防止烧毁驱动模块

2、倒立摆平衡系统
硬件配置
Arduino Mega 2560主控板
旋转编码器(AS5048A)
直流无刷电机(带FOC驱动)
金属摆杆(质量中心可调)
代码实现

#include <Encoder.h>
 
Encoder myEnc(2, 3);
float Kp=50, Ki=0.1, Kd=10;
float angleSetPoint=0, angle, error, integral, derivative;
long oldPosition  = -999;
int motorPWM=0;
 
void setup() {
    
    
  Serial.begin(9600);
}
 
void loop() {
    
    
  long newPosition = myEnc.read() / 4; // 4倍频
  if (newPosition != oldPosition) {
    
    
    float deltaAngle = (newPosition - oldPosition) * 0.08789; // 编码器分辨率转换
    angle += deltaAngle;
    oldPosition = newPosition;
  }
 
  error = angleSetPoint - angle;
  integral += error * 0.01;
  derivative = (error - lastError) / 0.01;
  motorPWM = Kp*error + Ki*integral + Kd*derivative;
 
  // 假设使用FOC驱动库
  // motorDriver.setPWM(motorPWM);
 
  lastError = error;
  delay(10);
}

技术要点
FOC驱动:通过磁场定向控制实现无刷电机的高效驱动
质量中心调整:通过改变摆杆配重位置优化系统阻尼比
状态观测器:采用卡尔曼滤波预测摆杆运动趋势
安全机制:当角度超过±45°时,自动切断电机电源

3、四足机器人单腿平衡
硬件配置
Arduino Due主控板
3轴力传感器(FSR402)
数字舵机(DS3218MG)
3D打印机械腿结构
代码实现

#include <Servo.h>
 
Servo kneeServo, hipServo;
float Kp=20, Ki=0.3, Kd=5;
float forceSetPoint=500, forceReading, error, integral, derivative;
int kneeAngle=90, hipAngle=90;
 
void setup() {
    
    
  kneeServo.attach(9); hipServo.attach(10);
  Serial.begin(9600);
}
 
void loop() {
    
    
  forceReading = analogRead(A0); // 假设A0连接力传感器
 
  error = forceSetPoint - forceReading;
  integral += error * 0.01;
  derivative = (error - lastError) / 0.01;
  int correction = Kp*error + Ki*integral + Kd*derivative;
 
  kneeAngle = constrain(kneeAngle + correction/2, 30, 150);
  hipAngle = constrain(hipAngle - correction/4, 30, 150);
 
  kneeServo.write(kneeAngle);
  hipServo.write(hipAngle);
 
  lastError = error;
  delay(20);
}

技术要点
力位混合控制:通过力传感器反馈调整关节角度,实现柔顺控制
虚拟模型控制:建立腿部动力学模型,预测接触力变化
碰撞检测:当力传感器读数突变时,触发紧急保护机制
步态规划:结合PID控制实现单腿的静态平衡与动态步态切换

通用优化策略
参数自整定:
临界比例度法:逐步增大Kp至系统等幅振荡,记录临界增益Kcr和振荡周期Tcr
公式计算:Kp=0.6Kcr, Ki=2Kp/Tcr, Kd=Kp*Tcr/8
抗干扰设计:
前馈补偿:根据已知扰动模型(如地面倾斜)提前调整控制输出
状态观测:使用扩展卡尔曼滤波(EKF)估计系统不可测状态
硬件优化:
选用低延迟传感器(如SPI通信的ICM-20948)
采用高速微控制器(如STM32F4系列)实现复杂算法
故障处理:
传感器失效检测:当连续10次读数无变化时,触发报警
机械故障保护:当电机电流超过阈值时,自动断电

在这里插入图片描述

4、倒立摆平衡控制

#include <PID_v1.h>

// 定义传感器读数(模拟)
float angle = 0.0; // 当前角度(单位:度)

// PID参数
double kp = 2.0, ki = 0.5, kd = 0.1;

// PID对象
PID balancePID(&angle, &motor_output, &target_angle, kp, ki, kd, DIRECT);

// 输出变量
float motor_output = 0.0; // 电机输出
float target_angle = 0.0; // 目标角度(直立平衡)

void setup() {
    
    
    Serial.begin(9600);

    // 初始化PID控制器
    balancePID.SetMode(AUTOMATIC);
    balancePID.SetOutputLimits(-100, 100); // 电机输出范围:-100% 到 +100%
}

void loop() {
    
    
    // 模拟传感器更新
    update_sensors();

    // 运行PID控制器
    balancePID.Compute();

    // 打印结果
    Serial.print("Angle: ");
    Serial.print(angle);
    Serial.print(", Target Angle: ");
    Serial.print(target_angle);
    Serial.print(", Motor Output: ");
    Serial.println(motor_output);

    delay(10); // 控制频率为100Hz
}

void update_sensors() {
    
    
    // 模拟传感器读数变化
    angle += (motor_output - 50) * 0.01; // 模拟角度变化
}

要点解读
目标值设定
target_angle设为0度,表示机器人需要保持直立状态。
实时调整
使用PID控制器根据当前角度与目标角度的偏差计算电机输出。
输出限制
设置合理的输出范围,避免电机过载或失控。
传感器模拟
使用简单的数学模型模拟角度变化,便于快速验证算法。
高频控制
控制频率设为100Hz,确保系统能够快速响应角度变化。

5、两轮自平衡车控制

#include <PID_v1.h>

// 定义传感器读数(模拟)
float pitch_angle = 0.0;  // 俯仰角(单位:度)
float yaw_rate = 0.0;     // 偏航角速度(单位:度/秒)

// PID参数
double kp_pitch = 3.0, ki_pitch = 0.2, kd_pitch = 0.1;
double kp_yaw = 1.5, ki_yaw = 0.1, kd_yaw = 0.05;

// PID对象
PID pitchPID(&pitch_angle, &pitch_output, &target_pitch, kp_pitch, ki_pitch, kd_pitch, DIRECT);
PID yawPID(&yaw_rate, &yaw_output, &target_yaw, kp_yaw, ki_yaw, kd_yaw, DIRECT);

// 输出变量
float pitch_output = 0.0; // 俯仰角控制输出
float yaw_output = 0.0;   // 偏航角控制输出
float target_pitch = 0.0; // 目标俯仰角(直立平衡)
float target_yaw = 0.0;   // 目标偏航角速度(稳定)

void setup() {
    
    
    Serial.begin(9600);

    // 初始化PID控制器
    pitchPID.SetMode(AUTOMATIC);
    yawPID.SetMode(AUTOMATIC);

    // 设置输出范围
    pitchPID.SetOutputLimits(-100, 100); // 俯仰角输出范围
    yawPID.SetOutputLimits(-50, 50);    // 偏航角输出范围
}

void loop() {
    
    
    // 模拟传感器更新
    update_sensors();

    // 运行PID控制器
    pitchPID.Compute();
    yawPID.Compute();

    // 打印结果
    Serial.print("Pitch Angle: ");
    Serial.print(pitch_angle);
    Serial.print(", Yaw Rate: ");
    Serial.print(yaw_rate);
    Serial.print(", Pitch Output: ");
    Serial.print(pitch_output);
    Serial.print(", Yaw Output: ");
    Serial.println(yaw_output);

    delay(10); // 控制频率为100Hz
}

void update_sensors() {
    
    
    // 模拟传感器读数变化
    pitch_angle += (pitch_output - 50) * 0.01; // 模拟俯仰角变化
    yaw_rate += yaw_output * 0.01;            // 模拟偏航角速度变化
}

要点解读
双环控制
使用两个独立的PID控制器分别控制俯仰角和偏航角速度。
稳定性增强
通过控制偏航角速度,减少自平衡车的转向抖动。
多维度解耦
俯仰角和偏航角速度的控制相互独立,避免耦合干扰。
扩展性
可进一步扩展为三轮或四轮平衡车控制。
实际应用优化
参数调整后适用于真实硬件,提升平衡性能。

6、带滤波的球形机器人平衡控制

#include <PID_v1.h>
#include <SimpleKalmanFilter.h> // 卡尔曼滤波库

// 定义传感器读数(模拟)
float raw_angle = 0.0; // 原始角度(单位:度)

// PID参数
double kp = 2.5, ki = 0.3, kd = 0.1;

// PID对象
PID balancePID(&filtered_angle, &motor_output, &target_angle, kp, ki, kd, DIRECT);

// 输出变量
float motor_output = 0.0; // 电机输出
float target_angle = 0.0; // 目标角度(直立平衡)

// 卡尔曼滤波器
SimpleKalmanFilter angle_filter(1, 1, 0.01);
float filtered_angle = 0.0; // 滤波后的角度

void setup() {
    
    
    Serial.begin(9600);

    // 初始化PID控制器
    balancePID.SetMode(AUTOMATIC);
    balancePID.SetOutputLimits(-100, 100); // 电机输出范围
}

void loop() {
    
    
    // 模拟传感器更新
    update_sensors();

    // 应用卡尔曼滤波
    filtered_angle = angle_filter.updateEstimate(raw_angle);

    // 运行PID控制器
    balancePID.Compute();

    // 打印结果
    Serial.print("Raw Angle: ");
    Serial.print(raw_angle);
    Serial.print(", Filtered Angle: ");
    Serial.print(filtered_angle);
    Serial.print(", Motor Output: ");
    Serial.println(motor_output);

    delay(10); // 控制频率为100Hz
}

void update_sensors() {
    
    
    // 模拟传感器读数变化
    raw_angle += (motor_output - 50) * 0.01; // 模拟角度变化
}

要点解读
卡尔曼滤波
使用卡尔曼滤波器对传感器数据进行平滑处理,减少噪声干扰。
滤波与控制结合
在PID控制之前对角度数据进行滤波,提升系统稳定性。
抗噪能力增强
卡尔曼滤波有效抑制随机噪声,提高平衡精度。
模块化设计
滤波和控制逻辑分离,便于维护和扩展。
实际应用扩展
可应用于更复杂的环境,如室外或高噪声场景。

注意,以上案例只是为了拓展思路,仅供参考。它们可能有错误、不适用或者无法编译。您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。

在这里插入图片描述