关于电机双闭环PID控制一些理解

原文地址:https://blog.csdn.net/sillykog/article/details/78566811?ops_request_misc=&request_id=&biz_id=102&utm_term=%E4%B8%89%E9%97%AD%E7%8E%AFPID%E6%8E%A7%E5%88%B6&utm_medium=distribute.pc_search_result.none-task-blog-2blogsobaiduweb~default-2-78566811.pc_v2_rank_blog_default&spm=1018.2226.3001.4450

双闭环结构
在这里插入图片描述

目前网上流传的一些关于双闭环的资料有很多我觉得是不对或者不够清楚的,在这边分享一下自己的理解,希望大家也能指点一下。
双闭环的作用
串级控制系统是改善控制质量的有效方法之一,在过程控制中得到了广泛的应用。所谓串级控制,就是采用两个控制器串联工作,外环控制器的输出作为内环控制器的设定值,由内环控制器的输出去操纵控制阀,从而对外环被控量具有更好的控制效果。这样的控制系统被称为串级系统。PID串级控制就是串级控制中的两个控制器均为PID控制器,它增强了系统的抗干扰性(也就是增强稳定性)。

  1. 增加系统的稳定性这点是正确的,因为电机转速电流双闭环的电流换增加了对电流的反馈控制,不至于使得电流过分超调。
  2. 但有观点认为电机双闭环可以加速启动,其实这点是不完全正确的,对于单闭环系统,只要允许较大的超调量,其实启动速度是足够快的。其实原观点表达的意思应该是加快系统启动到稳态的时间,也就是缩小调节时间。
    单双闭环区别
    双闭环比单闭环多了电流内环,用于控制电流的稳定性保证较小超调量和较好的稳定性,实际常用的简单单闭环控制系统中,为保证电流不超过电机承受极限,往往需要进行电流截止控制,另一方便未避免积分深度饱和,也需要对积分进行限幅,而为了达到快速启动的效果会给定较大的积分初值,如此一来,虽然可以勉强满足控制,但其实电流超调严重,而且稳定性较差。为此,双闭环可以减小电流的超调和过饱和现象,得到更加良好的控制效果。
    在这里插入图片描述

图一是双闭环控制下的启动电流
图二是双闭环控制下的转速波形
图三是单闭环控制下的电流波形
双闭环内环的输入问题
我们知道在单闭环系统中,输入转速差,转速控制器会输出对应的PWM来使得电机转速达到期望转速,其实我们已经默认了PWM和转速呈正相关关系。但在双闭环系统中,输入转速差,转速控制器会输出对应的电流大小,然后该电流与实际电流大小之差作为电流控制器的输入,再输出对应的PWM。这里面的疑问就是,我们怎么知道转速控制器对应特定转速差输出的对应电流大小应该是多少。(实际操作上我们其实就是瞎调pid而已,但其蕴含的原理是什么呢)
答:输出=速度误差××转动惯量/(采样时间××转矩系数)=(速度误差/采样时间)××转动惯量/转矩系数=加速度××转动惯量/转矩系数=转矩/转矩系数=转矩电流。

即转矩最适电流=速度差*p,由于该过程不一定线性,因此需要积分环节控制存在。

在解答中,我们揭示了在一定程度上,转矩电流与转矩成正比,进而与转速差成正比,这样一来确定了输入转速差,我们应该输出多少电流,就好像单闭环系统中,输入转速差,我们知道应该输出多少PWM一样,这里面同样有对应关系,但往往我们都将其当作黑箱操作,而事实上双闭环在调参的过程中也是当作黑箱操作的,这边只是在原理上为大家弄清楚电流和转速差的对应关系。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 电机PID速度位置闭环控制代码可以根据具体的电机和控制器进行相应的编写。下面是一个简单的范例供参考: ```c++ #include <PID_v1.h> // 定义电机控制相关的引脚 const int enablePin = 9; const int forwardPin = 10; const int backwardPin = 11; // 设置PID参数 double Kp = 1.0; double Ki = 1.0; double Kd = 0.0; // 设置目标速度和位置 double targetSpeed = 100; // 以某种单位表示的目标速度 double targetPosition = 500; // 以某种单位表示的目标位置 // 定义PID对象 PID speedPID(&currentSpeed, &output, &targetSpeed, Kp, Ki, Kd, DIRECT); PID positionPID(&currentPosition, &output, &targetPosition, Kp, Ki, Kd, DIRECT); void setup() { // 初始化电机相关的引脚 pinMode(enablePin, OUTPUT); pinMode(forwardPin, OUTPUT); pinMode(backwardPin, OUTPUT); // 设置PID的相关参数 speedPID.SetOutputLimits(-255, 255); // 设置输出范围 speedPID.SetSampleTime(50); // 设置采样时间 speedPID.SetMode(AUTOMATIC); // 设置为自动模式 positionPID.SetOutputLimits(-255, 255); positionPID.SetSampleTime(100); positionPID.SetMode(AUTOMATIC); } void loop() { // 获取当前速度和位置 int currentSpeed = getCurrentSpeed(); // 通过某种方式获取当前速度 int currentPosition = getCurrentPosition(); // 通过某种方式获取当前位置 // 运行速度和位置PID控制 speedPID.Compute(); positionPID.Compute(); // 根据输出控制电机 if (output > 0) { analogWrite(enablePin, output); digitalWrite(forwardPin, HIGH); digitalWrite(backwardPin, LOW); } else if (output < 0) { analogWrite(enablePin, -output); digitalWrite(forwardPin, LOW); digitalWrite(backwardPin, HIGH); } else { digitalWrite(enablePin, LOW); digitalWrite(forwardPin, LOW); digitalWrite(backwardPin, LOW); } delay(50); // 设置控制周期 } ``` 这是一个使用Arduino库中的`PID_v1`库实现的电机PID速度位置闭环控制代码示例。具体的电机和控制器接口等可能需要根据实际情况进行相应的修改。 如果你需要更详细的教程,可以参考一些相关的书籍或在线教程,例如《Arduino编程从零基础到精通》等。这些教程会涵盖更多的电机控制理论和实践,帮助你更好地理解和应用PID控制算法。 ### 回答2: 电机 PID(Proportional-Integral-Derivative)速度和位置闭环控制代码和教程可以根据具体的硬件平台和编程语言来编写。以下是一个基本的示例用于 Arduino 平台上的直流电机速度控制。 首先,你需要将电机与 Arduino 板连接。将电机的正极(通常是红色线)连接到驱动器或 H 桥的 VCC/VIN 引脚,并将电机的负极(通常是黑色线)连接到驱动器的 GND 引脚。随后,将驱动器与 Arduino 板连接。将驱动器的控制引脚连接到 Arduino 板的数字引脚上。 接下来,你可以使用 Arduino 编程软件创建一个新的项目,并添加如下代码: #include <PID_v1.h> // 定义电机引脚 #define MOTOR_PIN 3 // PID 参数 double Setpoint, Input, Output; double Kp = 1, Ki = 1, Kd = 1; PID motorPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); // 设置初始变量 void setup() { pinMode(MOTOR_PIN, OUTPUT); // 设置 PID 控制器 Setpoint = 100; // 目标速度 motorPID.SetMode(AUTOMATIC); // 设置串口通信(调试用) Serial.begin(9600); } void loop() { // 获取输入值(例如电机的旋转速度) Input = analogRead(A0); // 使用 PID 计算输出值 motorPID.Compute(); // 将输出值作为 PWM 信号发送到电机 analogWrite(MOTOR_PIN, Output); // 输出调试信息 Serial.print("Input: "); Serial.print(Input); Serial.print(", Output: "); Serial.println(Output); delay(100); } 在这个示例中,我们使用了名为 PID_v1 的库来实现 PID 控制器。首先,我们将电机的引脚定义为数字引脚3(可根据实际情况更改)。然后,我们设置了 PID 的参数和目标速度(Setpoint)。接下来,我们将电机的输入值读取到 Input 变量中,并使用 motorPID.Compute() 计算输出值。最后,我们将输出值作为 PWM 信号发送到电机,并通过串口输出调试信息。 这个示例只是一个简单的示范,实际应用中可能需要根据具体要求进行更改和优化。你可以参考 Arduino 官方网站、各种开发社区和教程来获取更详细的信息和示例代码。 ### 回答3: 电机PID速度位置闭环控制是一种常用的电机控制方法。下面是一个简单的示例代码,以及一个简化的教程。 代码示例: ```c #include <PID_v1.h> // 定义电机控制引脚 int motorPinA = 9; int motorPinB = 10; // 定义PID参数 double Setpoint, Input, Output; double Kp = 1, Ki = 1, Kd = 1; PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); void setup() { // 初始化串口通信 Serial.begin(9600); // 设置电机引脚为输出模式 pinMode(motorPinA, OUTPUT); pinMode(motorPinB, OUTPUT); // 设置PID参数 Setpoint = 100; // 设置目标速度或位置 Input = 0; myPID.SetMode(AUTOMATIC); } void loop() { // 读取当前速度或位置 Input = readEncoder(); // 替换为你自己的读取速度或位置的函数 // 计算PID输出 myPID.Compute(); // 输出控制信号到电机 if (Output > 0) { analogWrite(motorPinA, Output); // 正转 analogWrite(motorPinB, 0); } else { analogWrite(motorPinA, 0); analogWrite(motorPinB, abs(Output)); // 反转 } // 打印PID参数和输出 Serial.print("Kp:"); Serial.print(Kp); Serial.print(", Ki:"); Serial.print(Ki); Serial.print(", Kd:"); Serial.print(Kd); Serial.print(", Output: "); Serial.println(Output); delay(100); } ``` 教程: 1. 在代码中定义了一个电机控制引脚(例如9和10),以及一个PID对象。 2. 在`setup()`函数中,设置了串口通信,初始化电机引脚为输出模式,并设置了PID参数和目标值。 3. 在`loop()`函数中,首先读取当前速度或位置(通过`readEncoder()`函数来实现),然后使用PID对象计算输出控制信号。 4. 根据输出控制信号,分别控制两个电机引脚,使电机正转或反转。 5. 最后,使用串口通信打印PID参数和输出控制信号。 6. 在`delay()`函数中添加适当的延迟。 这只是一个简化的示例,实际应用中可能需要根据具体情况进行适当的修改和扩展。可以根据具体的项目需求,调整PID参数、目标值和控制方式,以实现所需的电机控制效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值