C# 实现模拟PID调试(学习专用无硬件)

news2024/9/21 2:32:34
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PID控制
{
    public class PIDModel
    {
        public float goal;           //定义设定值
        public float thisValue;        //定义实际值
        
        public float err_last;           //定义上一个偏差值
        public float err_last2;           //定义最上前的偏差值
        public float Kp, Ki, Kd;           //定义比例、积分、微分系数
        public float output;         //定义输出值
        public float err;               //定义误差值
        public float errSum;           //定义误差和(积分)
        public float errInteral;
        public float errInteral2;

        public PIDModel()
        {
            goal = 0.0f;
            thisValue = 0.0f;
            err = 0.0f;
            err_last = 0.0f;
            output = 0.0f;
            errSum = 0.0f;
            errInteral = 0.0f;
            Kp = 0.4f;
            Ki = 0.16f;
            Kd = 0.2f;
            output = 0.0f;
        }

        public float PosPID(float Goal)
        {
            goal = Goal;
            err = goal - thisValue;//误差值 = 设定值-实际值
            errSum += err;//误差的积分(误差和)
            errInteral = err - err_last;//误差的变化
            //Console.WriteLine("err " + err);
            output = Kp * err + Ki * errSum + Kd * errInteral;

            err_last = err;
            thisValue = output;
            return output;
        }

        public float IncrePID(float Goal)
        {
            goal = Goal;
            err = goal - thisValue;
           
            errInteral = err - err_last;//此次误差-上次误差

            errInteral2 = err_last - err_last2;//上次误差-上上次误差

            output = Kp * errInteral + Ki * err + Kd * (errInteral - errInteral2);
            thisValue += output;
            err_last2 = err_last;
            err_last = err;
            return thisValue;
        }
    }
}

using PID控制;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace PID视图
{
    public partial class Form1 : Form
    {
        Queue<float> DataQueues=new Queue<float>(100);

        PIDModel pIDModel = new PIDModel();
        public Form1()
        {
            InitializeComponent();
            timer1.Enabled = false;

            textBox1.Text = "0.2";
            textBox2.Text = "0.015";
            textBox3.Text = "0.2";
            textBox4.Text = "200";
            textBox5.Text = "195";
            trackBar1.Value = (int)pIDModel.thisValue;

        }

        private void Setting_MyChartUI(Chart thisChart)
        {
            #region 图表内部颜色
            thisChart.ChartAreas[0].BackColor = Color.FromArgb(33, 99, 106);
            #endregion

            #region x,y轴字体设置
            thisChart.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.FromArgb(205, 255, 255);
            thisChart.ChartAreas[0].AxisX.LabelStyle.Font = new Font("思源黑体 CN Bold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            #endregion

            #region 折线图横线颜色
            thisChart.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.FromArgb(205, 255, 255);
            #endregion

            #region 坐标轴箭头样式
            thisChart.ChartAreas[0].AxisX.ArrowStyle = AxisArrowStyle.Triangle;
            thisChart.ChartAreas[0].AxisY.ArrowStyle = AxisArrowStyle.Triangle;
            #endregion

            #region 坐标轴颜色
            thisChart.ChartAreas[0].AxisX.LineColor = Color.White;
            thisChart.ChartAreas[0].AxisY.LineColor = Color.White;
            #endregion

            #region x轴相邻间隔大小
            thisChart.ChartAreas[0].AxisX.Interval = 1;
            #endregion

            #region 线条的颜色
            thisChart.Series[0].Color = Color.FromArgb(100, 46, 199, 201);
            #endregion

            #region 点上的颜色
            thisChart.Series[0].MarkerColor = Color.Purple;
            #endregion

            #region 每一个点上数字的颜色
            thisChart.Series[0].LabelForeColor = Color.FromArgb(255, 179, 102);
            #endregion

            #region 在点上显示数字
            //thisChart.Series[0].IsValueShownAsLabel = true;
            #endregion

            #region 点上的图案
            thisChart.Series[0].MarkerStyle = MarkerStyle.Diamond;
            #endregion

            #region 包含范围的折线图类型 范围内和线条的颜色一致
            thisChart.Series[0].ChartType = SeriesChartType.SplineRange;
            #endregion
        }
        Random rd = new Random();

        int okCnt = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {
            Setting_MyChartUI(chart1);

            chart1.ChartAreas[0].AxisY.StripLines.Clear();//清除上一根线
            Setting_MyChartUI_YMaxMin(int.Parse(textBox4.Text), 0, chart1);
            Setting_MyChart_MakingLine(int.Parse(textBox4.Text), chart1);
            Setting_MyChart_MakingLine(int.Parse(textBox5.Text), chart1);


            #region 队列数据更新

            if (DataQueues.Count() < 1000)
            {
                
                DataQueues.Enqueue(pIDModel.PIDFun(type, float.Parse(textBox4.Text)));
            }
            else
            {
                DataQueues.Dequeue();
            }

            #endregion

            trackBar1.Value = (int)pIDModel.thisValue;

            #region 折线图刷新
            chart1.Series[0].Points.Clear();
            #endregion

            #region 折线图数据刷新
            for (int j = 0; j < DataQueues.Count(); j++)
            {
                chart1.Series[0].Points.AddXY(j + 2, DataQueues.ElementAt(j));

                if (PointIsOk(DataQueues.ElementAt(j), 195, 200))
                {
                    okCnt++;
                    chart1.Series[0].Color = Color.FromArgb(100, 46, 199, 201);
                    if(okCnt.Equals(50))
                    {
                        label6.Text = (DateTime.Now - lastTime).ToString();
                    }
                }
                else
                {
                    chart1.Series[0].Color = Color.FromArgb(100, 252, 86, 51); ;
                }
            }
            #endregion

            #region 关闭X轴名称
            chart1.ChartAreas[0].AxisX.Enabled = AxisEnabled.False;
            #endregion
        }

        private void Setting_MyChartUI_YMaxMin(int max, int min, Chart thischart)
        {
            thischart.ChartAreas[0].AxisY.Maximum = max * 1.09;
            //thischart.ChartAreas[0].AxisY.Minimum = min * 0.91;
            thischart.ChartAreas[0].AxisY.Minimum = -150;
        }

        private void Setting_MyChart_MakingLine(int lineMax, Chart thisChart)
        {
            #region 添加标识线
            StripLine stripLine = new StripLine();
            stripLine.Text = lineMax.ToString();//展示文本
            stripLine.BackColor = Color.Red;//背景色
            stripLine.Interval = 0;//间隔
            stripLine.IntervalOffset = lineMax;//偏移量
            stripLine.StripWidth = 0.003;//线宽
            stripLine.ForeColor = Color.White;//前景色
            stripLine.TextAlignment = StringAlignment.Near;//文本对齐方式
            thisChart.ChartAreas[0].AxisY.StripLines.Add(stripLine);
            #endregion
        }

        private bool PointIsOk(float val,int min, int max)
        {
            if(val > min && val < max)
            {
                return true;
            }
            return false;
        }
        int type = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            lastTime = DateTime.Now;
            type = 0;
            pIDModel.Kp = float.Parse(textBox1.Text);
            pIDModel.Ki = float.Parse(textBox2.Text);
            pIDModel.Kd = float.Parse(textBox3.Text);
            timer1.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            type = 1;
            pIDModel.Kp = float.Parse(textBox1.Text);
            pIDModel.Ki = float.Parse(textBox2.Text);
            pIDModel.Kd = float.Parse(textBox3.Text);
            timer1.Enabled = true;
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {

        }

        DateTime lastTime = new DateTime();
        private void button3_Click(object sender, EventArgs e)
        {
            okCnt=0;
            pIDModel = new PIDModel();
            timer1.Enabled = false;
            chart1.Series[0].Points.Clear();
            DataQueues.Clear();
        }

        private void trackBar1_ValueChanged(object sender, EventArgs e)
        {
            pIDModel.thisValue =  trackBar1.Value  ;
        }
    }
}

在这里插入图片描述

参考文章:
自动控制算法的学习笔记
PID控制算法的C语言实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/68282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DBCO-ICG-disulfo_二磺酸-吲哚菁绿-二苯并环辛炔_disulfo-ICG-DBCO

一、理论分析&#xff1a; 中文名&#xff1a;二磺酸-吲哚菁绿-二苯并环辛炔、水溶性吲哚菁绿-二苯基环辛炔 英文名&#xff1a;disulfo-ICG-DBCO、DBCO-ICG-disulfo CAS号&#xff1a;N/A 化学式&#xff1a;C63H62N4Na2O11S3 分子量&#xff1a;1193.37二、产品详情&#xff…

Bootstrap Table pagelist设置后失效

Bootstrap Table pagelist设置后不生效、失效、不起作用、不能使用问题。 前言 在使用Bootstrap Table进行数据展示时&#xff0c;设置pagelist选项后不生效。bootstrap版本为 v3.3.7。 经过 网上搜索尝试使用以下几种方式解决&#xff0c;发现均不行&#xff0c;你们可以参…

深入理解ReentrantReadWriteLock源码

1. ReentrantReadWriteLock简介 之前我们介绍过ReentrantLock&#xff0c;它是基于AQS同步框架实现的&#xff0c;是一种可重入的独占锁。但是这种锁在读多写少的场景下&#xff0c;效率并不高。因为当多个线程在进行读操作的时候&#xff0c;实际上并不会影响数据的正确性。 …

分享5款小众软件,大家按需下载

今天推荐一些可以大幅度提升办公效率的小软件&#xff0c;安全无毒&#xff0c;下载简单&#xff0c;最重要的是没有广告&#xff01; 1.进程调试——Process Lasso Process Lasso是一款独特的调试进程级别的系统优化工具 &#xff0c;主要功能是基于其特别的算法动态调整各个…

Linux——文件系统inode与软硬链接

目录 一.inode &#xff08;一&#xff09;.背景知识 &#xff08;二&#xff09;.inode 二.软硬链接 &#xff08;一&#xff09;.软链接 &#xff08;二&#xff09;.硬链接 一.inode &#xff08;一&#xff09;.背景知识 我们知道&#xff0c;磁盘是按磁道与扇区划分…

广告行业中那些趣事系列58:当我们面对文本分类任务的时,可以使用哪些优化策略...

导读&#xff1a;本文是“数据拾光者”专栏的第五十七篇文章&#xff0c;这个系列将介绍在广告行业中自然语言处理和推荐系统实践。本篇主要总结了一下我在实际项目中对于文本分类任务的优化策略&#xff0c;对于想要提升线上文本分类任务效果的小伙伴可能有所帮助。欢迎转载&a…

专访 | 罗成:开源并非“只可远观”

OpenMLDB: 请先来一段自我介绍吧。 罗成&#xff1a; 我是罗成&#xff0c;来自华中科技大学&#xff0c;目前研二在读&#xff0c;研究方向是云原生数据库的架构研究。 OpenMLDB: 请问是什么样的契机让你接触到了 OpenMLDB 呢&#xff1f; 罗成&#xff1a; 当时课余时间比…

skywalking链路追踪整合spring-cloud

skywalking安装资料 一、安装skywalking 将apache-skywalking-apm-bin.zip上传到/opt目录下2. 解压apache-skywalking-apm-bin.zip unzip apache-skywalking-apm-bin.zip&#xff0c;解压后即可使用&#xff0c;里面的配置文件都提前配置好了 3. 启动skywalking 进入apache-…

HTML做一个传统节日端午节 带设计报告4500字

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

征文连载丨在不修改数据库源码的情况下,如何提高 MogDB 对 Oracle 的兼容性?...

&#xff1a; 2022年8月4日至9月9日&#xff0c;墨天轮社区联合云和恩墨发起了首届「MogDB 主题征文活动」&#xff0c;邀请各位技术从业者学习、使用 MogDB 数据库&#xff0c;分享使用心得与实战案例&#xff0c;一起探索这款融合了众多创新特性的商业版企业级数据库。活动期…

[附源码]Python计算机毕业设计Django校园租赁系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Docker安装Jenkins

docker安装&#xff1a;可参考这里 拉取Jenkins镜像 docker pull jenkins/jenkins创建挂载目录并赋予777权限 mkdir /data/jenkins chmod 777 /data/jenkins运行Jenkins容器并设置名字、端口、目录、时间 50000:50000:前面端口是宿机的端口&#xff0c;&#xff1a;后面端口…

客服如何维护客户?

有网店工作经验的客服&#xff0c;都知道维护老客户的重要性&#xff0c;因为老客户关乎着商品的销量、店铺的升级、客户转化率的多少&#xff0c;因此客服需要通过好的售后服务留住大量的老客户。 前言 有网店工作经验的客服&#xff0c;都知道维护老客户的重要性&#xff0c…

LIBTIFF读取tiff文件时,打印buf出错

如图所示&#xff0c;按照官网提供的例程读取tiff文件&#xff0c;并打印读取的值时&#xff0c;提示&#xff1a; Subscript of pointer to incomplete type void 代码如下&#xff1a; //---打开tiff文件的测试TIFF* tif TIFFOpen("a.tif", "r");if(tif…

使用docker安装RocketMQ

1.创建namesrv服务拉取镜像docker pull rocketmqinc/rocketmq创建namesrv数据存储路径mkdir -p /docker/rocketmq/data/namesrv/logs /docker/rocketmq/data/namesrv/store构建namesrv容器docker run -d \ --restartalways \ --name rmqnamesrv \ -p 9876:9876 \ -v /docker…

如何用vue+免费的webdb 实现一个世界杯足球竞猜系统

一、前言 最近世界杯在如火如荼的进行。我们都知道&#xff0c;中国也派出了我们的一支强大的队伍&#xff1a;中国建筑队&#xff0c;全程参与了世界杯的所有比赛。 哈哈开个玩笑&#xff0c;不过说到世界杯&#xff0c;还真有不少朋友&#xff0c;不仅仅是看球&#xff0c;…

[附源码]Python计算机毕业设计Django疫情防控管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

手把手教你成为荣耀开发者:数据报表使用指引

荣耀开发者服务平台是荣耀面向开发者的统一生态入口&#xff0c;通过聚合周边内外部系统&#xff0c;分全球多站点部署&#xff0c;为全球开发者提供业务全生命周期的商业支撑服务&#xff0c;拥有应用分发、智慧服务、开放能力、HONOR Connect等众多业务等您来合作。 “数据报…

Partial differential equation

In mathematics, a partial differential equation (PDE) is an equation which imposes relations between the various partial derivatives of a multivariable function. The function is often thought of as an “unknown” to be solved for, similarly to how x is th…

【三维目标检测】SASSD(一)

SASSD是用于点云三维目标检测模型算法&#xff0c;发表在CVPR 2020《Structure Aware Single-stage 3D Object Detection from Point Cloud》&#xff0c;论文地址为“https://www4.comp.polyu.edu.hk/~cslzhang/paper/SA-SSD.pdf”。SASSD与基于Anchor的目标检测模型的结构基本…