双环PID控制详细讲解
参考博客:
(1)PID双环控制(速度环和位置环)
(2)PID控制(四)(单环与双环PID)
(3)内外双环pid算法
0 单环PID
目标位置→系统→速度→当前位置
输入目标位置,得到输出的位置是当前位置作为反馈量,而这个输出结果的位置量是我们通过控制中间过程量速度来控制的
单环控制的是速度量
1 PID双环控制

位置环做为外环,速度环作为内环。外环的输出值作为内环的目标值,外环计算一次pid,根据pid公式可以知道,当离位置目标越来越近时,第一个误差(外环误差)就越来越小,以至于输出的内环目标值就越来越小,所以最终达到的效果就是,离目标值越近,速度越小。(理想情况下,要调节好pid参数,不然系统也会崩溃)
双环控制的时候,外环PID参数调节幅度不要太大,这对于整个曲线的影响很大
代码实现步骤:
① PID参数结构体:定义位置、速度闭环的PID参数结构体变量
② 初始化PID参数:把目标值、期望值、累计偏差清零,配置PID系数

③ 设置目标位置:只要设置外环的,内环的不用设置,因为内环的目标值,就是外环的输出值。
④ PID双环控制
在定时器中断(1ms)里,每50ms计算一次当前编码器的总计数值,并通过这个值进行外环PID
(位置环)计算,得到目标速度,要经过速度限幅(防止速度过快),然后存放到g_motor_data.motor_pwm变量(临时存放而已),根据目标速度,再进行速度环PID计算,最终得出要输出的pwm比较值,存放g_motor_data.motor_pwm变量(最终存放),然后再限制pwm比较值输出

3 PID双环控制详细解析
如果采用PID双环控制,控制的其实就是加速度。如果直接输入目标位置,输出当前位置,控制直接是用加速度来控制这个位置显然是不稳定的。所以我们采用双环,用外环来输出目标速度,用内环来控制加速度从而来控制位置
总体流程:目标位置→系统1→目标速度→系统2→加速度→当前位置和速度→反馈回系统1和2
外环:目标位置→系统1→目标速度→反馈给系统1
外环控制的是速度,也就是通过输入目标位置,来控制速度,从而反馈给系统,当我们把目标速度调的比较稳定后,再把此输出的目标速度当作内环的目标值传进内环中
内环:目标速度→系统2→加速度→当前位置→反馈给系统2
内环是把外环的目标速度作为目标值,根据当前的速度控制加速度从而向目标加速度靠近,最后再把输出值作为反馈值
4 双环PID控制器的C++代码实现
float outer_pid_controller(float setpoint, float input, float kp, float ki, float kd, float dt) {static float integral = 0;static float prev_error = 0;float error = setpoint - input;// 计算积分项integral += error * dt;// 计算微分项float derivative = (error - prev_error) / dt;// 计算输出float output = kp * error + ki * integral + kd * derivative;// 更新上一个误差prev_error = error;return output;
}float inner_pid_controller(float setpoint, float input, float kp, float ki, float kd, float dt) {static float integral = 0;static float prev_error = 0;float error = setpoint - input;// 计算积分项integral += error * dt;// 计算微分项float derivative = (error - prev_error) / dt;// 计算输出float output = kp * error + ki * integral + kd * derivative;// 更新上一个误差prev_error = error;return output;
}float double_pid_controller(float setpoint, float input, float outer_kp, float outer_ki, float outer_kd, float inner_kp, float inner_ki, float inner_kd, float dt) {// 计算外环控制器输出float outer_output = outer_pid_controller(setpoint, input, outer_kp, outer_ki, outer_kd, dt);// 计算内环控制器输出float inner_output = inner_pid_controller(outer_output, input, inner_kp, inner_ki, inner_kd, dt);return inner_output;
}
outer_pid_controller和inner_pid_controller分别是外环和内环PID控制器的实现函数。double_pid_controller函数则是将两个PID控制器串联起来,实现双环PID控制器。其中,setpoint是设定值,input是输入值,outer_kp、outer_ki和outer_kd是外环控制器的比例、积分和微分系数,inner_kp、inner_ki和inner_kd是内环控制器的比例、积分和微分系数,dt是采样时间。该函数返回内环PID控制器的输出值。
百度Apollo纵向控制原理如下所示,该图可以为纵向控制器的设置提供参考:

可以看出纵向控制是基于Frenet坐标系的,位置跟踪控制器采用P控制器实现车辆位置闭环控制,速度跟踪控制器实现速度闭环控制,根据车辆的俯仰角得出坡道加速度补偿,以及预览点的加速度实现加速度开环控制。基于加速度和定位反馈纵向速度查找油门制动标定表得到油门和刹车的控制量,从而实现车辆的纵向控制。
6 油门刹车标定表
纵向控制逻辑:油门 --> 功率 --> 转速 / 扭矩 --> 车速 / 车加速度 --> 车加速
找到油门和v,a对应的关系

做实验,踩不同的油门,得到不同的v,a曲线

对于一个throttle,不同的时间 t 得到一系列v、a点,v,a可以合并,得到v,a曲线

不同的throttle会得到不同的v、a曲线

使用不同的throttle做实验,可以得到一个三维曲面

通过做实验,得到大量的(v,a,throttle)的三维点,从而拟合出throttle = f(v,a)
相关文章:
双环PID控制详细讲解
参考博客: (1)PID双环控制(速度环和位置环) (2)PID控制(四)(单环与双环PID) (3)内外双环pid算法 0 单环PID 目标位置→系…...
深入解析Java内存模型
一、背景 并发编程本质问题是:CPU、内存以及IO三者之间的速度差异。CPU速度快于内存、内存访问速度又远远快于IO,根据木桶理论,程序性能取决于最慢的操作,即IO操作。这样会出现CPU和内存交互时,CPU性能无法被充分利用…...
python使用国内镜像源
使用格式 格式为:pip install 库名 -i 镜像地址(注意空格的存在) pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple 推荐的镜像源: 清华大学(推荐):https://pypi.tuna.tsing…...
【动态规划】代码随想录算法训练营第四十六天 |139.单词拆分,关于多重背包,你该了解这些! ,背包问题总结篇!(待补充)
139.单词拆分 1、题目链接:. - 力扣(LeetCode) 2、文章讲解:代码随想录 3、题目: 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词…...
WordPress建站入门教程:如何选择和设置固定链接结构?
我们成功搭建好WordPress网站后,发布的文章对应的URL地址默认是使用“日期和名称型”,即是网站域名跟着的是年月日,最后是文章标题,如http://www.yigujin.com/2024/03/06/免费响应式WordPress博客主题JianYue/ 为了让我们的文章U…...
一款好用的AI工具——边界AICHAT(三)
目录 3.23、文档生成PPT演示3.24、AI文档翻译3.25、AI翻译3.26、论文模式3.27、文章批改3.28、文章纠正3.29、写作助手3.30、文言文翻译3.31、日报周报月报生成器3.32、OCR-DOC办公文档识别3.33、AI真人语音合成3.34、录音音频总结3.35、域方模型市场3.36、模型创建3.37、社区交…...
编程示例: 矩阵的多项式计算以javascript语言为例
编程示例: 矩阵的多项式计算以javascript语言为例 国防工业出版社的《矩阵理论》一书中第一章第8个习题 试计算2*A^8-3*A^5A^4A^2-4I A[[1,0,2],[0,-1,1],[0,1,0]] 代码如下 <html> <head> <title> 矩阵乘法 </title> <script srcset.js ><…...
project generator 简单使用
文章目录 1 progen 资源2 使用简介2.1 安装2.2 添加 target(可选)2.3 替换 CMake 模板(可选)2.4 创建 progen 项目 3 总结 1 progen 资源 0)简介:progen(project-generator,项目生成…...
C语言 —— 图形打印
题目1: 思路: 如果我们要打印一个实心正方形,其实就是一个二维数组,i控制行,j控制列,行列不需要控制,arr[i][j]直接打印星号即可。 对于空心正方形,我们只需要控制行和列的条件&…...
Python基础学习(11)常用模块
文章目录 一、time二、random三、os四、sys五、json补充1:JSON字符串补充2:JSON字符串和字典的区别 六、hashlib Python基础学习(1)基本知识 Python基础学习(2)序列类型方法与数据类型转换 Python基础学习(3)进阶字符串(格式化输出) Python基础学习(4)散…...
嵌入式学习37-TCP并发模型
TCP并发模型: 1.TCP多线程模型: 缺点: 1.创建线程会带来 资源开销 2.能够实现的 并发量 比较有限 2.IO模型: 1.阻塞IO: 没有…...
C语言字符函数和字符串函数
前言 今天这篇博客咱们一起来认识一些特殊的函数,在编程的过程中,我们经常要处理字符和字符串,为了方便字符和字符串,C语言提供了一些库函数,让我们一起看看这些函数都有什么功能吧!!࿰…...
Go语言必知必会100问题-22 空切片与nil切片有区别吗?
空切片与nil切片有区别吗? 很多开发人员经常混淆nil切片和空切片,不清楚什么时候使用空切片什么时候使用nil,而有些库函数又对这两者使用进行了区分。下面先来看看它们的定义。 空切片是length为0的切片当切片等于nil时为nil切片 下面是几种不同空切片…...
【C++进阶】C++多态概念详解
C多态概念详解 一,多态概念二,多态的定义2.1 多态构成的条件2.2 什么是虚函数2.3 虚函数的重写2.3.1 虚函数重写的特例2.3.2 override和final 2.4 重载和重写(覆盖)和重定义(隐藏)的区别 三,抽象…...
Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 2、线条平滑曲面但有间隔
环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 代码: import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata imp…...
前端精准测试调用链路分析
精准测试在评估需求的测试范围时,需要评估一下代码的影响范围,这个范围有两部分:一是需求直接修改的代码;二是修改代码影响到的功能模块。代码影响到的功能一般是通过调用链路分析来实现的,java和kotlin代码可以由java…...
Objective-C blocks 概要
1.block的使用 1.1什么是block? Blocks是C语言的扩充功能:带有自动变量(局部变量)的匿名函数。 “带有自动变量”在Blocks中表现为“截取自动变量" “匿名函数”就是“不带名称的函数” 块,封装了函数调用及调用…...
Linux操作系统-07-Linux安装应用
一、使用rpm安装应用(不推荐) 先下载到本地,以.rpm文件名结尾,下载完成后,再安装 rpm -qa | grep mysql #查询当前系统是否有下载过mysql包 先上传mysql的rpm安装包到linux的opt目录 安装 rpm -ivh …...
DevOps实战:Docker、Kubernetes与Jenkins的完美融合
DevOps与容器化技术:Docker、Kubernetes和Jenkins 引言 在软件开发领域,DevOps文化和容器化技术已经成为当今最热门的话题之一。DevOps的目标是缩短开发和运维之间的距离,提高软件交付的速度和质量。而容器化技术,如Docker和Kub…...
Python面向对象——程序架构
需求 创建图形管理器 -记录多种图形(圆形、矩形.) --提供计算总面积的方法, 要求:增加新图形,不影响图形管理器 测试: 创建图形管理器,存储多个图形对象。 通过图形管理器,调用计算总面积方法 思路 代码 # ------…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...
基于Uniapp的HarmonyOS 5.0体育应用开发攻略
一、技术架构设计 1.混合开发框架选型 (1)使用Uniapp 3.8版本支持ArkTS编译 (2)通过uni-harmony插件调用原生能力 (3)分层架构设计: graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...
Flask和Django,你怎么选?
Flask 和 Django 是 Python 两大最流行的 Web 框架,但它们的设计哲学、目标和适用场景有显著区别。以下是详细的对比: 核心区别:哲学与定位 Django: 定位: "全栈式" Web 框架。奉行"开箱即用"的理念。 哲学: "包含…...
【自然语言处理】大模型时代的数据标注(主动学习)
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构D 实验设计E 个人总结 A 论文出处 论文题目:FreeAL: Towards Human-Free Active Learning in the Era of Large Language Models发表情况:2023-EMNLP作者单位:浙江大…...
