Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于Python编写的pid控制器

基于Python编写的pid控制器

作者头像
云深无际
发布于 2021-09-14 08:16:00
发布于 2021-09-14 08:16:00
1.2K00
代码可运行
举报
文章被收录于专栏:云深之无迹云深之无迹
运行总次数:0
代码可运行

我是学数学的,不是学自动化的,啥啥的自动控制,啥啥的信号系统,我啥也不懂,在恶补。

最基本的一个pid控制器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import time


class PID:
    """PID Controller
    """

    def __init__(self, P=0.2, I=0.0, D=0.0, current_time=None):

        self.Kp = P
        self.Ki = I
        self.Kd = D

        self.sample_time = 0.00
        self.current_time = current_time if current_time is not None else time.time()
        self.last_time = self.current_time

        self.clear()

    def clear(self):
        """Clears PID computations and coefficients"""
        self.SetPoint = 0.0

        self.PTerm = 0.0
        self.ITerm = 0.0
        self.DTerm = 0.0
        self.last_error = 0.0

        # Windup Guard
        self.int_error = 0.0
        self.windup_guard = 20.0

        self.output = 0.0

    def update(self, feedback_value, current_time=None):
        """Calculates PID value for given reference feedback

        .. math::
            u(t) = K_p e(t) + K_i \int_{0}^{t} e(t)dt + K_d {de}/{dt}

        .. figure:: images/pid_1.png
           :align:   center

           Test PID with Kp=1.2, Ki=1, Kd=0.001 (test_pid.py)

        """
        error = self.SetPoint - feedback_value

        self.current_time = current_time if current_time is not None else time.time()
        delta_time = self.current_time - self.last_time
        delta_error = error - self.last_error

        if (delta_time >= self.sample_time):
            self.PTerm = self.Kp * error
            self.ITerm += error * delta_time

            if (self.ITerm < -self.windup_guard):
                self.ITerm = -self.windup_guard
            elif (self.ITerm > self.windup_guard):
                self.ITerm = self.windup_guard

            self.DTerm = 0.0
            if delta_time > 0:
                self.DTerm = delta_error / delta_time

            # Remember last time and last error for next calculation
            self.last_time = self.current_time
            self.last_error = error

            self.output = self.PTerm + \
                (self.Ki * self.ITerm) + (self.Kd * self.DTerm)

    def setKp(self, proportional_gain):
        """Determines how aggressively the PID reacts to the current error with setting Proportional Gain"""
        self.Kp = proportional_gain

    def setKi(self, integral_gain):
        """Determines how aggressively the PID reacts to the current error with setting Integral Gain"""
        self.Ki = integral_gain

    def setKd(self, derivative_gain):
        """Determines how aggressively the PID reacts to the current error with setting Derivative Gain"""
        self.Kd = derivative_gain

    def setWindup(self, windup):
        """Integral windup, also known as integrator windup or reset windup,
        refers to the situation in a PID feedback controller where
        a large change in setpoint occurs (say a positive change)
        and the integral terms accumulates a significant error
        during the rise (windup), thus overshooting and continuing
        to increase as this accumulated error is unwound
        (offset by errors in the other direction).
        The specific problem is the excess overshooting.
        """
        self.windup_guard = windup

    def setSampleTime(self, sample_time):
        """PID that should be updated at a regular interval.
        Based on a pre-determined sampe time, the PID decides if it should compute or return immediately.
        """
        self.sample_time = sample_time
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import PID
import time
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import BSpline, make_interp_spline  # Switched to BSpline


def test_pid(P=0.2,  I=0.0, D=0.0, L=100):
    """Self-test PID class
    .. note::
        ...
        for i in range(1, END):
            pid.update(feedback)
            output = pid.output
            if pid.SetPoint > 0:
                feedback += (output - (1/i))
            if i>9:
                pid.SetPoint = 1
            time.sleep(0.02)
        ---
    """
    pid = PID.PID(P, I, D)

    pid.SetPoint = 0.0
    pid.setSampleTime(0.01)

    END = L
    feedback = 0

    feedback_list = []
    time_list = []
    setpoint_list = []

    for i in range(1, END):
        pid.update(feedback)
        output = pid.output
        if pid.SetPoint > 0:
            feedback += (output - (1/i))
        if i > 9:
            pid.SetPoint = 1
        time.sleep(0.02)

        feedback_list.append(feedback)
        setpoint_list.append(pid.SetPoint)
        time_list.append(i)

    time_sm = np.array(time_list)
    time_smooth = np.linspace(time_sm.min(), time_sm.max(), 300)

    # feedback_smooth = spline(time_list, feedback_list, time_smooth)
    # Using make_interp_spline to create BSpline
    helper_x3 = make_interp_spline(time_list, feedback_list)
    feedback_smooth = helper_x3(time_smooth)

    plt.plot(time_smooth, feedback_smooth)
    plt.plot(time_list, setpoint_list)
    plt.xlim((0, L))
    plt.ylim((min(feedback_list)-0.5, max(feedback_list)+0.5))
    plt.xlabel('time (s)')
    plt.ylabel('PID (PV)')
    plt.title('TEST PID')

    plt.ylim((1-0.5, 1+0.5))

    plt.grid(True)
    plt.show()


if __name__ == "__main__":
    test_pid(1.2, 1, 0.001, L=50)
#    test_pid(0.8, L=50)

测试用代码

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云深之无迹 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Mysql数据库总结
– 1.创建数据库 CREATE DATABASE mybase; – 2.创建数据库并指定字符集 CREATE DATABASE mybase1 CHARACTER SET UTF8; – 3.查看所有数据库 SHOW DATABASES; – 4.查看当前使用的数据库 SELECT DATABASE(); – 5.修改数据库 ALTER DATABASE mybase CHARACTER SET UTF8; – 6.删除数据库 DROP DATABASE mybase1; – 切换数据库 USE mybase;
Twcat_tree
2022/11/30
3740
Mysql数据库总结
MySQL表的增删查改
values左侧为表中属性,右侧为自定义插入的内容,左右两侧安装顺序是一一对应的,如果顺序不同就会导致类型不同而出错。
每天都要进步呀
2023/10/16
4420
MySQL表的增删查改
学会Mysql第二天
完整的SQL查询指令: select select选项 字段列表 from 数据源 where条件 group by 分组 having 条件 order by 排序 limit 限制
白胡杨同学
2020/04/11
8310
简单的增 删 改 查
一:insert语句 into 关键字是可选的 values关键字前面的()是可选的,这里是要接收数据的列 values后面,有两种方式提供值 1:显式的给出值  2:从select语句中导出值
liulun
2022/05/08
5290
MySQL基础 — 常用命令
使用select对列进行查询时,不仅可以直接以列的原始值作为结果,而且还可以将列值进行计算后所得值作为查询结果,即select子句可以查询表达式的值,表达式可由列名、常量及算术运算符组成。 查询结果计算列显示“无列名”,一般要给计算列加列标题。 其中:表达式中可以使用的运算符有:加+、减-、乘*、除/、取余%
全栈程序员站长
2022/07/02
2.1K0
MySQL基础 — 常用命令
【MySql】聚合函数&&group by&&OJ题目
MySQL中的聚合函数用于对数据进行计算和统计,常见的聚合函数包括下面列举出来的聚合函数:
平凡的人1
2023/10/15
2510
【MySql】聚合函数&&group by&&OJ题目
《数据库查询:解锁数据宝藏的魔法之钥》
MySQL查询是一种用于检索、筛选和分析数据的数据库操作技术。作为一个强大的关系型数据库管理系统(RDBMS),MySQL支持多种查询方法,包括使用SQL(Structured Query Language)编写的查询语句。
杨不易呀
2023/09/27
2330
《数据库查询:解锁数据宝藏的魔法之钥》
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
学生表中存在一个birth字段,这个字段表示学生的出生年份。而运用MySQL的算术运算符用当前的年份减学生出生的年份,那么得到的就是这个学生的实际年龄数据。
盛透侧视攻城狮
2024/10/22
3050
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
数据仓库开发 SQL 使用技巧总结
作者:dcguo 使用 sql 做数仓开发有一段时间了,现做一下梳理复盘,主要内容包括 sql 语法、特性、函数、优化、特殊业务表实现等。 mysql 数据结构 常用 innodb 存储为 B+ 树 特点 多路平衡树,m 个子树中间节点就包含 m 个元素,一个中间节点是一个 page(磁盘页) 默认 16 kb; 子节点保存了全部得元素,父节点得元素是子节点的最大或者最小元素,而且依然是有序得; 节点元素有序,叶子节点双向有序,便于排序和范围查询。 优势 平衡查找树,logn 级别 crud; 单一节点比二
腾讯技术工程官方号
2022/07/19
3.3K0
数据仓库开发 SQL 使用技巧总结
阶段02JavaWeb基础day04mysql
数据仓库.就与我们之前学过的纯文本,properties这些技术一样.用来保存数据.并提供对数据进行增删改查的操作.我们以后做项目时, 项目中的数据都是保存在数据库中的. //-------------------------------------------------------------------- 为什么要用数据库,数据库的特点 1>实现数据共享
对弈
2019/09/04
5610
MySQL秘籍之索引与查询优化实战指南
最左前缀原则。不冗余原则。最大选择性原则。所谓前缀索引,说白了就是对文本的前几个字符建立索引(具体是几个字符在建立索引时去指定),比如以产品名称的前 10 位来建索引,这样建立起来的索引更小,查询效率更快!
千寻简
2025/01/03
2510
MySQL秘籍之索引与查询优化实战指南
Mysql入门
主流数据库包括:MS SQL Server, Oracle,DB2,Informix, Sybase 等。
jinghong
2020/05/12
1.3K0
Mysql入门
sql server之数据库语句优化
一切都是为了性能,一切都是为了业务 一、查询的逻辑执行顺序 (1) FROM left_table (3) join_type JOIN right_table (2) ON join_condition (4) WHERE where_condition (5) GROUP BY group_by_list (6) WITH {cube | rollup} (7) HAVING having_condition (8) SELECT (9) DISTINCT (11) top_specification
逸鹏
2018/04/09
1.6K0
MySQL 从入门到实践,万字详解!
数据库是往全栈发展不得不跨过的一道坎,大家不可避免会学到用到相关知识,最近查资料的时候发现网上很多内容要么就特别深,要么不成体系,对一些希望浅尝辄止仅仅是使用一下的人不太友好。最近刚好有机会学到 MySQL,集中一些时间学习了一下 MySQL 同时做了一些笔记,每个概念基本都有代码示例,每一行都是在下手打,读者可以直接复制了代码到命令行中运行,希望对大家有所帮助~ 😜 本文介绍的知识都不是特别深,目标用户是对 MySQL 零基础或弱基础的小伙伴们,可以帮助对 MySQL 建立一些概念,至少碰到相关问题知道
前端下午茶
2022/03/22
2.1K0
MySQL 从入门到实践,万字详解!
MySQL(四)
基本语法: insert into {表名}({字段列表}) values({值列表1}), ({值列表2}), …
1ess
2021/11/01
9940
【云原生进阶之数据库技术】第一章MySQL-2.3-数据基本操作
2、语法:select distinct from 表名; 去掉重复项,对应的字段前加符号表达:
江中散人_Jun
2024/02/24
2110
【云原生进阶之数据库技术】第一章MySQL-2.3-数据基本操作
Vc数据库编程基础MySql数据库的表查询功能
  不管是任何数据库.都会有查询功能.而且是很重要的功能.上一讲知识简单的讲解了表的查询所有.
IBinary
2019/05/25
9.8K0
理解SQL原理SQL调优你必须知道的10条铁律
原文地址: http://www.nowamagic.net/librarys/veda/detail/1502 我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,如果数据量大,人员流动大,那么我们还能保证下一段时间系统还能流畅的运行吗?我们还能保证下一个人能看懂我们的存储过程吗? 要知道sql语句,我想我们有必要知道sqlserver查询分析器怎么执行我么sql语句的,我么很多人会看执行计划,或者用profile来监视和调优查询语句或
Albert陈凯
2018/04/04
1.3K0
MySQL基础学习笔记
1.基础概念 1.1 相关概念与常用命令 数据库的好处 1.持久化数据到本地 2.可以实现结构化查询,方便管理 常见概念 1、DB:数据库,保存一组有组织的数据的容器 2、DBMS:数据库管理系统,又称为数据库软件(产品),用于管理DB中的数据 3、SQL: 结构化查询语言,用于和DBMS通信的语言 数据库存储数据的特点 1、将数据放到表中,表再放到库中 2、一个数据库中可以有多个表,每个表都有一个的名字,用来标识自己。表名具有唯一性。 3、表具有一些特性,这些特性定义了数据在表中如何存储,类似java中“
素履coder
2022/02/17
1.1K0
MySQL数据库完整知识点梳理----保姆级教程!!!
在字段名前面加上DISTINCT ,这里对于重复的字段,就只会显示最先出现的那个,后面重复的不会显示
大忽悠爱学习
2021/11/15
6K0
推荐阅读
相关推荐
Mysql数据库总结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验