p3项目-模拟 PID 控制器用来调节直流电机的转速

pid_control.py代码

python 复制代码
"""
PID Motor Control Simulation
Author: Bochra Oudha
Date: October 2025
Description:
    This simulation demonstrates how a PID controller (Proportional, Integral, Derivative)
    can control the speed of a DC motor. The system starts with zero speed and tries to 
    reach a target (setpoint) speed using feedback control.
"""

import numpy as np
import matplotlib.pyplot as plt

# PID parameters
Kp = 0.8   # Proportional gain
Ki = 0.4   # Integral gain
Kd = 0.05  # Derivative gain

# Simulation parameters
dt = 0.01                     # Time step
time = np.arange(0, 10, dt)   # 10 seconds
setpoint = 1.0                # Desired speed (normalized)
speed = 0.0                   # Initial motor speed
integral = 0.0
previous_error = 0.0

speeds = []
controls = []

# Simulation loop
for t in time:
    # Calculate error
    error = setpoint - speed
    
    # Integrate error
    integral += error * dt
    
    # Derivative of error
    derivative = (error - previous_error) / dt
    
    # PID control law
    control = Kp * error + Ki * integral + Kd * derivative
    
    # Simple motor model (speed response)
    speed += (control - 0.2 * speed) * dt
    
    # Save data
    previous_error = error
    speeds.append(speed)
    controls.append(control)

# Plot results
plt.figure(figsize=(10, 6))

# Speed vs Time
plt.subplot(2, 1, 1)
plt.plot(time, [setpoint]*len(time), 'r--', label='Setpoint')
plt.plot(time, speeds, 'b', label='Motor Speed')
plt.title('PID Motor Speed Control Simulation')
plt.xlabel('Time [s]')
plt.ylabel('Speed')
plt.legend()
plt.grid()

# Control signal
plt.subplot(2, 1, 2)
plt.plot(time, controls, 'g', label='Control Signal')
plt.xlabel('Time [s]')
plt.ylabel('Control Effort')
plt.legend()
plt.grid()

plt.tight_layout()
plt.show()

代码目的:让电机转速从 0 开始,慢慢追到目标速度 1.0。

feedback control(反馈控制)= 根据当前输出和目标的差距,不断修正输入。

PART1-PID参数

python 复制代码
# PID parameters
Kp = 0.8   # Proportional gain
Ki = 0.4   # Integral gain
Kd = 0.05  # Derivative gain

Kp = 0.8------比例项增益。意思是误差越大,现在施加的控制就越大。

Ki = 0.4------积分项增益。把过去一直存在的误差累积起来,再进行补偿。它主要解决的问题是**稳态误差。**也就是系统看起来快到了,但总差一点点,长期到不了目标值。这时候积分项就会慢慢把那点残余误差补掉。

Kd = 0.05------微分项增益。微分项看的是误差变化得快不快。如果误差变化太猛,说明系统可能冲得太快了,容易超调,这时候 D 项会起到一种"刹车"或者"预判"的作用。

PART2-仿真参数

python 复制代码
# Simulation parameters
dt = 0.01                     # Time step
time = np.arange(0, 10, dt)   # 10 seconds
setpoint = 1.0                # Desired speed (normalized)
speed = 0.0                   # Initial motor speed
integral = 0.0
previous_error = 0.0

这一段是在初始化系统。

dt = 0.01 时间步长

time = np.arange(0, 10, dt) 生成从 0 到 10 秒的时间序列,步长是 0.01。本质是一个数组(类似列表)

setpoint = 1.0 目标速度

speed = 0.0 初始电机速度是 0

integral = 0.0 积分项初始值

previous_error = 0.0 上一时刻误差

PART3-保存结果的列表

python 复制代码
speeds = []
controls = []

这两个列表用来记录每一步的数据,最后画图就靠它们。

speeds:存每个时刻的电机速度

controls:存每个时刻的控制量

PART4-主循环

python 复制代码
# Simulation loop
for t in time:

对每一个时间点,都做一次控制计算。也就是在每个离散时刻,控制器都重新看一下现在的情况,然后决定下一步怎么调。

1.算误差

python 复制代码
error = setpoint - speed

误差 = 目标值 - 当前输出

2.积分误差

python 复制代码
integral += error * dt

把当前这一步的误差累积到总误差里

3.计算误差变化率

python 复制代码
derivative = (error - previous_error) / dt

这就是微分项

4.PID控制律

python 复制代码
control = Kp * error + Ki * integral + Kd * derivative

控制量 = 比例项 + 积分项 + 微分项

PART5-电机模型

python 复制代码
speed += (control - 0.2 * speed) * dt

可以拆解为speed = speed + (control - 0.2 * speed) * dt

意思是 新的速度 = 旧速度 + 速度变化量,而 (control - 0.2 * speed) 相当于"速度变化趋势"。

control 是控制器给电机的驱动力**,**它会让速度上升。

- 0.2 * speed 是阻尼项 / 损耗项,速度越大,这个阻碍越大。

对应 dspeed/dt = control - 0.2 * speed

PART6-更新和保存数据

python 复制代码
previous_error = error
speeds.append(speed)
controls.append(control)

previous_error = error 把当前误差保存下来,给下一次循环算微分项用。

speeds.append(speed) 把当前速度保存到列表。

controls.append(control) 把当前控制量保存到列表。

PART7-画图部分

1.建图窗口

python 复制代码
plt.figure(figsize=(10, 6))

创建一个图窗,尺寸是 10×6。

2.第一张图:速度响应

python 复制代码
plt.subplot(2, 1, 1)
plt.plot(time, [setpoint]*len(time), 'r--', label='Setpoint')
plt.plot(time, speeds, 'b', label='Motor Speed')
plt.title('PID Motor Speed Control Simulation')
plt.xlabel('Time [s]')
plt.ylabel('Speed')
plt.legend()
plt.grid()

这部分是在画上面的图。

plt.subplot(2, 1, 1)

表示整张图分成 2 行 1 列,现在画第 1 个子图。

plt.plot(time, [setpoint]*len(time), 'r--', label='Setpoint')

画目标速度线,也就是红色虚线。因为目标始终是 1.0,所以它是一条水平线。

这里 len(time) 是1000,那么 [setpoint] * 1000 就是 [1.0, 1.0, 1.0, ..., 1.0] 。这样写是因为

因为 plt.plot(x, y) 要求x 和 y 必须一样长。

plt.plot(time, speeds, 'b', label='Motor Speed')

画真实电机速度,也就是蓝线。这条线会从 0 开始,逐渐逼近 1.0,可能有一点超调。

3.第二张图:控制信号

python 复制代码
plt.subplot(2, 1, 2)
plt.plot(time, controls, 'g', label='Control Signal')
plt.xlabel('Time [s]')
plt.ylabel('Control Effort')
plt.legend()
plt.grid()

这部分画的是控制量。

PART8-最后两句

python 复制代码
plt.tight_layout()
plt.show()

plt.tight_layout() 自动调整子图间距,防止标签重叠。

plt.show() 把图显示出来。

PART8-讲一讲Kd

Kd重点在于derivative的符号(正负号),

python 复制代码
derivative=(error -previous_error) / dt

情况1:误差在减小(好现象),比如

python 复制代码
previous_error = 1.0
error = 0.5

那么

python 复制代码
derivative = (0.5 - 1.0)/dt = 负数

代入控制

python 复制代码
control = ... + Kd * (负数)

control 会变小,这意味着 系统在接近目标 → D项帮你"踩刹车"

误差增大时候同理。

相关推荐
路飞雪吖~2 小时前
【测试】接口测试---1个框架,5个模块
开发语言·python·测试工具
q_35488851532 小时前
计算机毕业设计:Python居民出行规律可视化分析系统 Django框架 可视化 数据分析 PyEcharts 交通 深度学习(建议收藏)✅
人工智能·python·数据分析·车载系统·django·汽车·课程设计
FL16238631292 小时前
基于yolov26的荔枝成熟度检测系统python源码+pytorch模型+评估指标曲线+精美GUI界面
pytorch·python·yolo
iuu_star2 小时前
宝塔Linux部署python常遇问题解决
开发语言·python·腾讯云
Dream of maid2 小时前
Python基础4(函数)
开发语言·python
vx_biyesheji00012 小时前
计算机毕业设计:Python城市交通出行模式挖掘系统 Django框架 可视化 数据分析 PyEcharts 交通 深度学习(建议收藏)✅
人工智能·python·深度学习·数据分析·django·汽车·课程设计
yuanmazhiwu2 小时前
计算机毕业设计:Python智慧出行数据分析与模式识别系统 Django框架 可视化 数据分析 PyEcharts 交通 深度学习(建议收藏)✅
人工智能·python·算法·数据分析·django·flask·课程设计
bKYP953cL2 小时前
Flask - 常见应用部署方案
后端·python·flask
Dream of maid2 小时前
Python-基础1(数据类型)
开发语言·python