舵机PID控制

news2024/12/23 4:33:30

目录

舵机工作原理

 舵机PID控制

原理介绍

 代码

主代码

赋值PWM寄存器

 限制PWM赋值

 取绝对值

 位置式PID控制

 位置式离散PID


舵机工作原理

控制电路接收信号源的控制脉冲,并驱动电机转动:控制电路接收来自遥控器或者单片机的控制信号,然后驱动电机进行转动。

齿轮组将电机的速度成大倍数缩小,并将电机的输出扭矩放大响应倍数,然后输出:齿轮组起到了减速和增加扭矩的作用,让电机的输出更适合舵机的操作。

电位器和齿轮组的末级一起转动,测量舵机轴转动角度:通过电位器和齿轮组,我们可以测量舵机轴的转动角度,也就是舵机当前停留的位置。

电路板检测并根据电位器判断舵机转动角度,然后控制舵机转动到目标角度或保持在目标角度:电路板会根据电位器测量的角度信息来判断舵机的位置,并根据设定的目标角度来控制舵机是否需要继续转动或者停留在目标位置。

模拟舵机需要一个外部控制器(遥控器的接收机或者单片机)产生脉宽调制信号来告诉舵机转动角度,脉冲宽度是舵机控制器所需的编码信息:最后,模拟舵机需要外部的控制器产生特定脉冲宽度的调制信号,来告诉舵机应该转动到什么角度,脉冲宽度对应着舵机应该停留的位置。舵机的控制脉冲周期是20毫秒,脉宽从0.5毫秒到2.5毫秒,分别对应着-90度到+90度的位置(对于180°舵机)。

 有关舵机控制的可以阅读这篇文章:stm32f1的一个定时器多路pwm控制舵机_stm32舵机pwm程序-CSDN博客

 舵机PID控制

原理介绍

已知舵机的控制只需要给定一个 PWM 信号和合适的电源,就可以控制它转动的角度(实现位置控制)。如果我们要进行 PID 闭环控制,就必须有一个反馈值,但在这种情况下我们实际上是没有的。因此,我们需要调整我们的策略。由于舵机自带位置闭环控制功能,假设:只要给定范围内的目标位置信号,舵机都能到达该位置。也就是说,当前控制周期的输出目标位置会作为下一个控制周期的已知测量位置。

简单点就是:假设舵机具有良好的位置闭环控制能力,能够准确地到达我们所指定的目标位置。因此,在每个控制周期结束时,我们可以将当前周期的目标位置视为下一个周期的起始位置,从而实现连续的位置控制。

注意的是:这种假设的前提是确保每个控制周期的控制幅度不会超出舵机的响应范围,以确保舵机能够按照我们的期望进行位置调节。就是它上一个周期的控制信号确实抵达了, 因此我们需要确认我们每个周期的控制幅度在它的响应范围内。

假设当系统的控制周期为10毫秒,每个周期控制位置运动10个单位(先不考虑具体单位)。通过离散化,我们可以计算出舵机的控制速度:v=10/10ms=1/ms。这意味着每毫秒舵机的位置变化了1个单位。

我们知道舵机的控制脉冲周期是50赫兹,对应着脉冲宽度在0.5毫秒到2.5毫秒之间,分别对应-90度到+90度的角度范围。假设输出值A=10000时对应100%占空比,那么脉冲宽度在0.5毫秒到2.5毫秒之间对应的A值分别为:0.5/2010000=250 和 2.5/2010000=1250。即为 Amax -Amin =1000 对应 90-(-90) =180°。 对应着90度到-90度的角度范围。这里的10和之前提到的1000是相对应的。所以10对应的角度就是180°/1000*10=1.8°。考虑到单位时间是10毫秒,所以舵机的速度是 V=1.8°/10ms=18°/s。

通过这样的计算,我们可以将舵机的速度与其参数进行比较。假设舵机的速度参数是0.14秒/60°=428°/s,我们可以发现设定的速度远小于舵机本身的参数,因此响应时间是完全足够的。

  

外部提供一个控制信号,表示系统应该达到的目标位置。通过上一个周期的控制输出值,计算出系统上一个周期已经到达的位置,并将该位置作为位置PID控制器的输入。位置PID控制器根据当前位置和目标位置之间的误差,计算出一个控制输出值,用于调节系统朝目标位置移动。对于控制输出值,根据设定的目标速度进行限幅处理,确保控制信号不会过大。将经过限幅处理后的控制信号进行位置积分,以便更好地追踪目标位置的变化。最后,通过单片机输出PWM信号,控制系统执行相应的动作,实现位置控制。

 代码

主代码

int Target_Velocity=20,Position=250,Target_Position=250; //Position为当前值,Target_Position为目标值
float Position_KP=120,Position_KI=0.1,Position_KD=500; //PID参数
int TIM1_UP_IRQHandler(void)  
{    
	if(TIM_GetFlagStatus(TIM1,TIM_FLAG_Update)==SET)//10ms定时器中断
	{   
		TIM_ClearITPendingBit(TIM1,TIM_IT_Update);     //清除定时器中断标志位	                                        
		Moto=Position_PID(Position,Target_Position);    //位置PID
		Moto=Xianfu(Moto,Target_Velocity);              //PWM限幅
		Set_Pwm(Moto);
		
	}       	
	 return 0;	  
} 

首先,定义了三个变量:Target_Velocity表示目标转速,Position表示当前位置,Target_Position表示目标位置。

然后,定义了三个PID参数:Position_KP、Position_KI和Position_KD,用于控制PID算法的比例、积分和微分项的权重。

在定时器中断中,通过调用Position_PID函数实现位置式离散PID控制算法,计算出需要输出的PWM值,然后通过Xianfu函数对PWM进行限幅,最后通过Set_Pwm函数将PWM值输出到舵机上,控制舵机。

 

赋值PWM寄存器

void Set_Pwm(int moto)
{
	Position+=moto;
	if(Position>1250)Position=1250;
	if(Position<250)Position=250;
	TIM_SetCompare1(TIM2,Position);
		
}

设置PWM信号的占空比,控制舵机的位置。代码中的变量Position代表当前PWM信号的占空比值,moto是控制舵机转动的参数,表示需要增加或减少的占空比值。

在函数中,我们先将moto的值加到Position上,然后进行范围限制。如果Position大于1250,说明舵机已经转到最大角度位置,就将Position设置为1250;如果Position小于250,说明舵机已经转到最小角度位置,就将Position设置为250。

最后,通过调用STM32的TIM_SetCompare1函数,将Position的值设置为PWM信号的占空比,从而控制舵机的位置。

 限制PWM赋值

int Xianfu(int value,int Amplitude)
{	
	int temp;
	if(value>Amplitude) temp = Amplitude;
	else if(value<-Amplitude) temp = -Amplitude;
	else temp = value;
	return temp;		
}

 用于对给定的数值value进行幅值限制,限制的幅值为Amplitude。函数返回限制后的数值。

函数逻辑如下:

  • 如果value大于幅值Amplitude,则将temp赋值为Amplitude。
  • 否则,如果value小于负幅值-Amplitude,则将temp赋值为-Amplitude。
  • 否则,即value在-Amplitude和Amplitude之间,则将temp赋值为value。

最后,函数返回temp,即经过幅值限制处理后的数值。

 取绝对值

int myabs(int a)
{ 		   
	  int temp;
		if(a<0)  temp=-a;  
	  else temp=a;
	  return temp;
}

 位置式PID控制

int Position_PID (int position,int target)
{ 	
	 static float Bias,Pwm,Integral_bias,Last_Bias;
	 Bias=target-position;                                 
	 Integral_bias+=Bias;	                                 
	 Pwm=Position_KP*Bias/100+Position_KI*Integral_bias/100+Position_KD*(Bias-Last_Bias)/100;       
	 Last_Bias=Bias;                                       
	 return Pwm;                                          
}

根据当前位置和目标位置计算输出PWM值来控制某个系统。下面是代码中各变量和计算步骤的解释:

  • static float Bias, Pwm, Integral_bias, Last_Bias; 这些变量在函数调用之间保持其值不变,并且仅在定义它们的代码块内可见。

  • Bias = target - position; 计算当前位置与目标位置之间的偏差(误差)。

  • Integral_bias += Bias; 累积偏差,用于计算积分项。

  • Pwm = Position_KP * Bias / 100 + Position_KI * Integral_bias / 100 + Position_KD * (Bias - Last_Bias) / 100; 根据比例、积分和微分项计算PID输出值。其中Position_KP、Position_KI和Position_KD分别代表位置式PID控制器的比例增益、积分增益和微分增益。

  • Last_Bias = Bias; 将当前偏差保存为上一次的偏差,用于计算微分项。

  • return Pwm; 返回计算得到的PWM输出值。

 位置式离散PID

上述PID涉及了位置式离散PID,这里做出通俗讲解:

将其比喻成一个自动驾驶的汽车。想象一下,你想让汽车保持在某个特定的位置上。首先,你测量了当前汽车的位置和目标位置之间的距离差,就像计算出当前位置和目标位置之间的误差一样。然后,根据这个误差,你做出调整,来使汽车朝着目标位置靠近。这个调整的过程可以分成三个部分。

第一部分是比例项,就像你在开车时会根据距离调整方向盘的角度。如果距离很远,你就会转动方向盘很多,如果距离很近,你就会轻轻转动方向盘。比例项就是根据误差的大小来调整控制输出的。

第二部分是积分项,就像你在开车时会根据持续时间来调整方向盘的角度。如果你一直偏离目标位置,那么积分项会逐渐累积,使得调整力度更大,以便纠正系统的静态误差。

第三部分是微分项,就像你在开车时会根据速度的变化来调整方向盘的角度。如果你的速度变化很大,你就会小心地调整方向盘。微分项通过比较当前误差和上一次误差的变化率,来调整控制输出,以防止系统出现过度振荡。

最后,将这三个部分的调整结果相加,得到一个控制输出值,就像你根据方向盘的调整来驾驶汽车一样。这个输出值会通过离散的时间间隔持续发送给系统,实现对系统位置的精确控制。

通过这种方式,位置式离散PID算法可以帮助我们在控制系统中实现准确的位置控制,就像自动驾驶汽车一样,将系统稳定地驶向目标位置。

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

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

相关文章

milligram css 源码浅析

一、前言 milligram 是我在 20 年接触并使用的一个 CSS 库&#xff0c;他的出现时间已经无法溯源了&#xff0c;根据 npm 上的发布时间最早是 2015 年&#xff0c;而在国内名气起来的时间大概就是 2020 年了&#xff0c;同时 milligram 最后的更新也停在了那一年。 由于当时只…

[工具探索]VSCode介绍和进阶使用

相比较GoLand、PhpStorm、PyCharm、WebStorm的重量级内存占用&#xff0c;从Windows系统来&#xff0c;各种卡死&#xff0c;换到MacOS倒不会卡死&#xff0c;但是内存占用太多&#xff0c;影响体验&#xff0c;决定换到VSCode。当然这个过程需要适应过渡期&#xff0c;旧伙计都…

C++入门 上(命名空间 缺省参数 函数重载)

C入门 上 命名空间命名空间定义命名空间使用 C输入输出缺省参数缺省参数概念缺省参数分类 函数重载函数重载概念C支持函数重载的原理--名字修饰 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用…

阿里云服务器部署配置选择全攻略

阿里云服务器配置怎么选择&#xff1f;根据实际使用场景选择&#xff0c;个人搭建网站可选2核2G配置&#xff0c;访问量大的话可以选择2核4G配置&#xff0c;企业部署Java、Python等开发环境可以选择2核8G配置&#xff0c;企业数据库、Web应用或APP可以选择4核8G配置或4核16G配…

ActiveMQ高可用架构涉及常用功能整理

ActiveMQ高可用架构涉及常用功能整理 1. activemq的集群模式2. 镜像模式高可用系统架构和相关组件2.1 架构说明2.2 相关概念说明2.3 消息模型2.3.1 点对点2.3.2 发布订阅 3. activemq常用命令4. activemq配置集群5. 疑问和思考5.1 activemq的数据删除策略是怎样的&#xff1f;5…

已解决:IDEA中@Autowired自动注入MyBatis Mapper报红警告的几种解决方法

今天在使用 IDEA 使用 MyBatis 的时候遇到了这种情况&#xff1a; 可以看到 userMapper 下有个红色的波浪警告&#xff0c;虽然代码没有任何问题&#xff0c;能正常运行&#xff0c;但是这个红色警告在这里杵着确实让人很窝心。 于是我在网上找了找&#xff0c;最终明白了原因…

使用静态CRLSP配置MPLS TE隧道

正文共&#xff1a;1591 字 13 图&#xff0c;预估阅读时间&#xff1a;4 分钟 静态CRLSP&#xff08;Constraint-based Routed Label Switched Paths&#xff0c;基于约束路由的LSP&#xff09;是指在报文经过的每一跳设备上&#xff08;包括Ingress、Transit和Egress&#xf…

DBeaver通用数据库管理 连接DM8 数据库及其配置

一.工具版本说明 DBeaver版本: 21.0.202106012023&#xff0c; 推荐官网下载。 DM8/达梦数据库: DM 8 Windows 官网安装手册 如果想深入了解DM8 数据库操作请参考&#xff1a;DM8/达梦 数据库管理员使用手册详解 二.DM8/达梦驱动下载 下载渠道/官方文档 DM 8/达梦技术…

LeetCode JS专栏刷题笔记(一)

一、前言 LeetCode 在前不久出了一个 JavaScript 专栏&#xff0c;这个专栏一个目的是为了非前端工程师学习 JS&#xff0c;另一个是为了前端工程师提升 JS 能力。 因此在这个专栏中&#xff0c;基本不涉及什么具体算法问题&#xff0c;都是一些 JS 的入门语法与常见的 JS 面…

Maven(基础)、MyBatis

简介 Apache Maven是一个项目管理和构建工具&#xff0c;它基于项目对象模型 (POM)的概念&#xff0c;通过一小段描述信息来管理项目的构建、报告和文档 官网: http://maven.apache.org/ Maven作用 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#x…

Elasticsearch查询报错 Result window is too large

一现象&#xff1a; es数据分页查询前端提示系统异常&#xff0c;后端报错日志 二根本原因&#xff1a; 默认情况下&#xff0c;Elasticsearch 限制了 from size 参数的组合不能超过 10,000 条记录&#xff0c;用于防止查询大数据集时对系统资源的过度消耗 三解决办法&#…

JavaSE——面向对象基础(1/4)-面向对象编程、程序中的对象、对象的产生、对象的执行原理、类和对象的一些注意事项

目录 面向对象编程 程序中的对象 对象的产生 对象的执行原理 类和对象的一些注意事项 面向对象编程 开发一个一个的对象&#xff0c;把数据交给对象&#xff0c;再调用对象的方法来完成对数据的处理。 例如设计一个学生的对象&#xff0c;其中有姓名和成绩等&#xff0c…

可视化视频监控平台EasyCVR如何配置服务参数以免getbaseconfig接口信息泄露?

可视化云监控平台/安防视频监控系统EasyCVR视频综合管理平台&#xff0c;采用了开放式的网络结构&#xff0c;平台支持高清视频的接入和传输、分发&#xff0c;可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集…

【.NET Core】C#编程规范

【.NET Core】C#编程规范 文章目录 【.NET Core】C#编程规范一、概述1.1 结构清晰第一1.2 简洁之风1.3 代码风格保持一致性 二、命名约定三、类型参数命名指南3.1 请使用描述性名称命名泛型类型参数&#xff0c;除非单个字面名称完全具有自我说明性且描述性名称不会增加任何作用…

Redis(03)——发布订阅

基础命令 基于频道 publish channel message&#xff1a;将信号发送到指定的频道pubsub subcommand [argument [argyment]]&#xff1a;查看订阅或发布系统状态subscribe channel [channel]&#xff1a;订阅一个或多个频道的信息unsubscribe [channel [channel]]&#xff1a;退…

CSS:BFC

BFC&#xff0c;Block Formatting Context&#xff0c;块级格式化上下文&#xff0c;是一个独立的渲染区域或隔离的独立容器&#xff0c;它决定了其子元素如何布局&#xff0c;并且与这个区域外部的元素无关。 形成 BFC 的条件 float 的值不为 none&#xff08;left、right&a…

【Node.js和Appium server的下载安装步骤】

Node.js 是JavaScript的运行环境&#xff0c;是 JS 语言的解释器&#xff0c;之中集成了npm库。 npm 是世界上最大软件包仓库&#xff0c;可用于Appium server安装。 1、Node.js官方安装包及源码下载地址&#xff1a;Node.js 选择相应系统的安装包进行下载&#xff08;.msi用…

c编译器学习02:chibicc文档翻译

目的 先粗略地看一遍作者的书籍。 原文档地址 https://www.sigbus.info/compilerbook# “低レイヤを知りたい人のためのCコンパイラ作成入門” 为想了解底层的人准备的C编译器制作入门 Rui Ueyama ruiucs.stanford.edu 2020-03-16 作者简介 https://www.sigbus.info/ 植山…

知识蒸馏实战代码教学二(代码实战部分)

一、上章原理回顾 具体过程&#xff1a; &#xff08;1&#xff09;首先我们要先训练出较大模型既teacher模型。&#xff08;在图中没有出现&#xff09; &#xff08;2&#xff09;再对teacher模型进行蒸馏&#xff0c;此时我们已经有一个训练好的teacher模型&#xff0c;所以…

C++ 二分模版 数的范围

给定一个按照升序排列的长度为 n 的整数数组&#xff0c;以及 q 个查询。 对于每个查询&#xff0c;返回一个元素 k 的起始位置和终止位置&#xff08;位置从 0 开始计数&#xff09;。 如果数组中不存在该元素&#xff0c;则返回 -1 -1。 输入格式 第一行包含整数 n 和 q &…