ARDUINO PID
ardupilot pid参数

ardupilot pid参数【实用版】目录1.Ardupilot 简介2.PID 参数的含义3.PID 参数的调整方法4.PID 参数对飞行控制的影响5.总结正文1.Ardupilot 简介Ardupilot 是一个开源的自动驾驶系统,可以用于无人机、机器人等设备的自主控制。
它基于 Arduino 平台,提供了丰富的功能和接口,方便开发者进行定制和扩展。
在 Ardupilot 中,飞行控制器(FC)是一个核心组件,它负责处理各种传感器的数据,并计算出相应的控制信号,以实现对飞行器的精确控制。
2.PID 参数的含义PID(Proportional-Integral-Derivative,比例 - 积分 - 微分)是一种广泛应用于工业控制和机器人控制领域的算法。
在 Ardupilot 中,PID 参数主要用于调整飞行控制器的控制精度和响应速度。
具体来说,PID 参数包括三个参数:Kp(比例增益)、Ki(积分增益)和 Kd(微分增益)。
3.PID 参数的调整方法调整 PID 参数是提高飞行控制器性能的关键。
一般来说,调整 PID 参数需要一定的经验和技巧。
以下是一些常用的调整方法:- 试错法:通过不断尝试不同的参数组合,观察飞行器的反应,逐步找到最佳的参数组合。
- Ziegler-Nichols 方法:这是一种基于频域分析的调整方法,需要计算飞行器的开环传递函数,并根据其频率特性来确定 PID 参数。
- 实验法:通过模拟实际飞行环境,在实际飞行中观察飞行器的表现,逐步调整 PID 参数。
4.PID 参数对飞行控制的影响PID 参数对飞行控制器的性能有着重要影响。
以下是 PID 参数对飞行控制的影响:- Kp(比例增益):Kp 决定了控制器对误差的响应速度。
Kp 越大,控制器对误差的响应越快,但可能导致系统震荡。
- Ki(积分增益):Ki 决定了控制器对长时间存在的误差的消除能力。
Ki 越大,控制器对长时间存在的误差越敏感,但过大的 Ki 可能导致系统响应变慢。
arduino舵机控制

arduino舵机控制第一章:引言引言部分将介绍Arduino(亦称为Genuino)舵机控制的背景和意义,舵机的概述,以及本论文的研究目的和框架。
第二章:舵机控制原理及方法本章将介绍舵机的工作原理和控制方法。
首先,对舵机的构成和工作原理进行简要介绍,包括电机、位置反馈和驱动电路等方面。
然后,介绍传统的舵机控制方法,如PWM控制和位置控制,以及最近的一些控制方法,如PID控制和闭环控制。
最后,讨论Arduino对舵机控制的适用性和优势。
第三章:Arduino舵机控制系统设计在本章中,将详细介绍基于Arduino的舵机控制系统的设计。
首先,介绍Arduino的硬件和软件环境,包括Arduino开发板、Arduino IDE编程环境和各种相关的库函数。
然后,介绍舵机的连接方式,包括电源和信号线的连接。
接着,介绍舵机控制系统的软件设计,包括初始化舵机、设定目标位置和控制舵机运动的实现方法。
最后,进行系统功能测试和性能评估。
第四章:实验结果与讨论在这一章中,将介绍本研究设计的Arduino舵机控制系统的实验结果和讨论。
首先,介绍实验的设置和操作步骤。
然后,展示实验结果,包括舵机运动的准确性和控制精度等方面。
最后,对实验结果进行讨论,包括系统性能的评估和改进的建议。
结论本论文研究了Arduino舵机控制的原理、方法和实现,设计了基于Arduino的舵机控制系统,并通过实验验证了系统的可行性和性能。
结果表明,Arduino在舵机控制领域具有优势和应用潜力。
未来的工作可以进一步改进系统性能,并扩展到更广泛的舵机应用领域中。
继续写相关内容:第二章:舵机控制原理及方法2.1 舵机的工作原理舵机是一种能够精确控制角度位置的电机。
它由电机和位置反馈系统组成。
电机通过输出转矩来驱动舵盘转动,而位置反馈系统可以测量舵盘的实际位置,并将实际位置与目标位置进行比较,从而进行相应的修正。
2.2 传统的舵机控制方法传统的舵机控制方法主要包括PWM(Pulse Width Modulation)控制和位置控制。
Arduino编码器小车左右转速同步的PID调节实验

digitalWrite(E_left, LOW); }
//主程序段
void loop()
{
if (Serial.available()>0) //如果 Arduino 控制器读缓冲区中存在上位机下达的字节
{
val_start= Serial.read(); //从读缓冲区中读取上位机的三个控制字节
一个有趣的实验,可以边实验边观察。如果您拿起这个编码器小车,用手摩擦小车的 左轮,左轮的转速变慢,在 PID 比例算式的作用下,右轮电机的 PWM 功率值会变小, 以使右轮速度也跟着变慢。这时,再把手移到小车右轮,右轮遇到阻力时,为了保证依然 与左轮转速同步,在 LabVIEW 前面板反馈的右电机 PWM 功率值,您会观察到它的值再 不断增加。所以一个 PID 比例算法的功效,通过编码器小车这个物理设备和 LabVIEW 这个人机交互界面,就真真切切地感受到了。
//初始化程序段
void setup()
{
启动串口通信,波特率为 Serial.begin(9600); //
9600b/s
pinMode(M_left, OUTPUT); //L298P 直流电机驱动板的控制端口设置为输出模式
pinMode(E_left, OUTPUT);
pinMode(M_right, OUTPUT);
int val_right; //小车右轮电机的 PWM 功率值
int val_start;//上位机控制字节,用于控制电机是否启动;
int val_FB; //上位机控制字节,用于控制电机是正转还是反转;
int val_left;//上位机控制字节,用于提供给左轮电机 PWM 功率值。
int count1 = 0; //左轮编码器码盘脉冲计数值
使用PID库,轻松搞定PID(上)

使用PID库,轻松搞定PID(上)最近才知道有PID库这个东西,既然有PID库,那就可以像其他的库一样,通过调用库里的函数,就可以轻松地实现PID了。
pid库可以在https:///br3ttb/Arduino-PID-Library/这里下载。
然后配合着库里给的例程和这篇帖子,应该就会使用PID了。
——————————————————————————————————————————————————————————————————我很好奇地看了一下库给的介绍。
我觉得写得很基础、易懂。
于是就翻译到这儿吧,给自己也备一个份。
原文的地址在这儿:还参考了每个接触PID的人,都知道PID的公式吧:然后根据这个公式,就可以编出计算output的arduino程序如下:图像 4.png (14.97 KB, 下载次数: 343)下载附件2015-4-13 14:39 上传注:程序源码可以在原文上复制。
可是在上面的程序中,当PID不规则的调用时就会出现两个问题:1.有时候定时调用,有时候又停止调用,将得不到PID的持续稳定特性。
2.需要额外对积分和微分进行数学计算,因为他们都是和时间息息相关的。
解决方法:保证PID在一个固定的的时间间隔内被调用,我通过每个周期内事先设置好的采样时间调用compute函数,PID再决定是计算还是立即返回数值。
一旦我们知道PID在固定时间间隔内被调用,积分和微分的计算就能被简化。
于是我们的程序就变成了:灰色部分是新加的语句。
在这个新的程序中,作者在29行把时间转化为秒。
这样可以简化运算。
同时新加入后面两个函数把PID参数转化为以秒为基准的参数。
当上面的PID程序在运行中,可能会出现微分过冲的问题。
看上面的图,因为error=Setpoint-Input,只要Setpoint发生改变,就会导致error的值发生一个突变。
在微分运算里这种微分值的突变是无穷大的。
解决方法:于是我们的程序就变成了:可以看到我们只是用-dInput代替掉了+dError。
PID自动控制巡线arduino

#include <PID_v1.h>double Setpoint, Input, Output;void PID_MY();double Kp=5, Ki=0.8, Kd=5;void fun1();void fun2();int num1,num2,num3,num4,num5,num6,num7,num8;//8路循迹PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd,P_ON_M, DIRECT);int pinI1=26;//定义I1接口int pinI2=27;//定义I2接口int pinI3=28;int pinI4=29;int pinI5=30;//定义I1接口int pinI6=31;//定义I2接口int pinI7=32; //一high一LOW 正转int pinI8=33;int P1=2;//定义EA(PWM调速)接口int P2=3;//定义EA(PWM调速)接口int P3=4;//定义EA(PWM调速)接口int P4=5;//定义EA(PWM调速)接口//1,3左同侧电机,对应PWM1void FORWARD(int PWM1,int PWM2);void BACK(int PWM1,int PWM2);void LEFT(int PWM1,int PWM2);void RIGHT(int PWM1,int PWM2);void STOP();void PID_my();void input_hong();void hong();void setup(){pinMode(pinI1,OUTPUT);pinMode(pinI2,OUTPUT);pinMode(pinI3,OUTPUT);pinMode(pinI4,OUTPUT);pinMode(pinI5,OUTPUT);pinMode(pinI6,OUTPUT);pinMode(pinI7,OUTPUT);pinMode(pinI8,OUTPUT);pinMode(P1,OUTPUT);pinMode(P2,OUTPUT);pinMode(P3,OUTPUT);pinMode(P4,OUTPUT);//initialize the variables we're linked to Input=0;Setpoint = 0;//turn the PID onmyPID.SetMode(AUTOMATIC);myPID.SetSampleTime(10);myPID.SetOutputLimits(-255, 255);attachInterrupt(4, fun1,RISING);//当电平上升时,触发中断函数,21 attachInterrupt(3, fun2,RISING);//22pinMode(P1,OUTPUT);pinMode(P2,OUTPUT);pinMode(pinI1,OUTPUT);pinMode(pinI2,OUTPUT);pinMode(pinI3,OUTPUT);pinMode(pinI4,OUTPUT);//马达pinMode(19,INPUT); //1pinMode(20,INPUT); //8pinMode(48,INPUT); //2pinMode(46,INPUT); //3pinMode(44,INPUT); //4pinMode(36,INPUT); //5pinMode(38,INPUT); //6pinMode(40,INPUT); //7delay(4000);PID_MY();}void loop() {}void PID_MY(){int PWM1,PWM2;while(1){hong();input_hong();//根据红外输入inputpute();if(Output>=0){PWM1=255;PWM2=(int)(255-Output);}else{PWM1=(int)(255+Output);PWM2=255;}FORWARD(PWM1,PWM2);if(num5==HIGH&&num6==HIGH&&num7==HIGH){LEFT(255,255);delay(100);}if(num3==HIGH&&num4==HIGH&&num5==HIGH&&num6==HIGH) {detachInterrupt(3);detachInterrupt(4);FORWARD(255,255);delay(500);STOP();return;}}}void input_hong(){if(num2==HIGH)Input = -16;else if(num3==HIGH) Input = -8;else if(num4==HIGH) Input = -0.5;else if(num5==HIGH) Input = 1.5;else if(num6==HIGH) Input = 8;else if(num7==HIGH) Input = 16;}void hong(){num1=digitalRead(20); num2=digitalRead(36);num3=digitalRead(38);num4=digitalRead(40);num5=digitalRead(44);num6=digitalRead(46);num7=digitalRead(48);num8=digitalRead(21);// 用num1-8保存从左到右8个传感器的状态 }void fun1(){do{num4=digitalRead(44);RIGHT(255,255);}while(num4!=HIGH);}void fun2(){do{num5=digitalRead(36);LEFT(255,255);}while(num5!=HIGH);}void FORWARD(int PWM1,int PWM2){analogWrite(P1,PWM1);digitalWrite(pinI1,LOW);digitalWrite(pinI2,HIGH);analogWrite(P2,PWM2);digitalWrite(pinI3,LOW);digitalWrite(pinI4,HIGH);analogWrite(P3,PWM1);digitalWrite(pinI5,LOW);digitalWrite(pinI6,HIGH);analogWrite(P4,PWM2);digitalWrite(pinI7,LOW);digitalWrite(pinI8,HIGH);}void BACK(int PWM1,int PWM2) {analogWrite(P1,PWM1);digitalWrite(pinI1,HIGH);digitalWrite(pinI2,LOW);analogWrite(P2,PWM2);digitalWrite(pinI3,HIGH);digitalWrite(pinI4,LOW);analogWrite(P3,PWM1);digitalWrite(pinI5,HIGH);digitalWrite(pinI6,LOW);analogWrite(P4,PWM2);digitalWrite(pinI7,HIGH);}void LEFT(int PWM1,int PWM2) {analogWrite(P1,PWM1);digitalWrite(pinI2,LOW);digitalWrite(pinI1,HIGH);analogWrite(P2,PWM2);digitalWrite(pinI4,HIGH);digitalWrite(pinI3,LOW);analogWrite(P3,PWM1);digitalWrite(pinI6,LOW);digitalWrite(pinI5,HIGH);analogWrite(P4,PWM2);digitalWrite(pinI7,LOW);digitalWrite(pinI8,HIGH);}void RIGHT(int PWM1,int PWM2) {analogWrite(P1,PWM1);digitalWrite(pinI2,HIGH);digitalWrite(pinI1,LOW);analogWrite(P2,PWM2);digitalWrite(pinI4,LOW);analogWrite(P3,PWM1); digitalWrite(pinI6,HIGH); digitalWrite(pinI5,LOW); analogWrite(P4,PWM2); digitalWrite(pinI8,LOW); digitalWrite(pinI7,HIGH); }void STOP(){digitalWrite(pinI1,HIGH); digitalWrite(pinI2,HIGH); digitalWrite(pinI3,HIGH); digitalWrite(pinI4,HIGH); digitalWrite(pinI5,HIGH); digitalWrite(pinI6,HIGH); digitalWrite(pinI7,HIGH); digitalWrite(pinI8,HIGH); }。
基于单片机的pid电机调速控制系统的硬件电路设计

下面是一个基于单片机的PID电机调速控制系统的硬件电路设计示例:
电路中使用了一个STM32F103C8T6微控制器,该MCU内置了PWM输出、ADC输入、定时器计数等功能,非常适合用于电机调速控制。
电机驱动采用了L298N模块,可以
控制两个直流电机的转速和方向。
另外,根据需要,可以加入光电编码器或霍尔传感
器等来获取电机的转速反馈信号。
电路中还使用了一个LCD1602液晶屏来显示电机转速、目标速度、PWM输出等信息,方便用户进行调试和监控。
此外,还可以使用按键开关来控制电机的启停和目标速度
的调节。
在硬件电路设计完成后,需要编写单片机程序来实现PID控制算法、PWM输出、
ADC采样等功能。
通常可以使用Keil、IAR等集成开发环境来编写和调试程序,也可
以使用Arduino IDE等编程环境进行开发。
这只是一个简单的PID电机调速控制系统的硬件电路设计示例,具体的实现方式和细
节可能会因应用场景和需求的不同而有所不同。
基于UP board的PID直流电机控制设计

64 | 电子制作 2020年04月0 引言2020年,机器人迎来了正式工业应用的第58个年头。
在各种各样的新兴科技技术发展的推动下,机器人已经成为改变未来世界的颠覆性科技之一。
机器人技术正从以前的工业阶级向家庭、教育、娱乐、救援等阶级迅速发展。
因此产生了多种优秀的机器人软件框架,而机器人操作系统ROS 就是最适合我们来进行机器人开发的最常用的软件框架,本文主要也是研究了ROS 的使用。
同时还选取了Arduino 电机驱动板来作为受控的下位机,Arduino 是一款容易上手、灵活使用的开源电子平台,主要是能够轻松的与各类传感器、电子元件和拓展模块进行结合。
通过了研究调查,我从而选取了UP board 开发板作为搭载ROS 的主要载体,通过ROS 独特的分布式通信机制,进而利用多种功能包实现了模块间的点对点的松耦合连接,同时根据独特的PID 控制算法来对Arduino 电机驱动板进行调节,进而实现对于小车的辅助控制。
1 总体设计方案该算法的主要研究是建立在UP board 开发板上的,UP board 板上搭载是ROS(机器人操作系统),PID 算法主要是由此系统来进行的,通过Arduino 电机控制板上的MPU6050陀螺仪加速度模块和两个直流电机上所搭载的编码器所读取到的数据来对小车实现控制。
整体方案主要分成两个部分,一部分是上位机控制,主要包含了UP board 开发板、ROS(机器人操作系统)、8400mAh 容量5V 输出的电池。
而另外一部分则是受控的下位机,主要包含了TB6612NG 电机驱动模块、MPU6050陀螺仪加速模块、AB相位霍尔编码器、Teensy3.2。
图1 总体设计方案2 各个组成部分本设计设计主要是通过MPU16050陀螺仪加速度计模块和AB 相位霍尔编码器进行读取数据,将读取的数据通过Teensy3.2进行传输,传输到上位机中进行系统运算,上位机选取的是UPboard 开发板,开发板中主要搭载了Ubuntu 16.04系统上的ROS Kinetic 版本,ROS 中有许多性能完善的功能的包可以供我们进行开发使用,最后将处理好的数据再通过Teensy3.2传回Arduino 控制板的TB6612电机驱动模块进行电机驱动。
基于arduino的直流电机模糊PID控制

基于 arduino的直流电机模糊 PID控制摘要:一般直流电动机调速均采用典型的PID器调速,但由于其具有不自适应性,在调速参数变化时,不能保证电机在高速和变速的过程中的稳定性和高精度。
现设计一基于arduino芯片为核心的具有自适应的模糊PID调速器,不仅运行简单,还能够改善直流电机在高速运转时的稳定性。
关键字:Arduino 模糊PID 直流电机调速0引言由于直流电机控制简单,效率高,所以在大多工业生产中应用广泛。
但在直流电机调速中,由于参数改变,电机往往在高速运转中难以稳定,传统的PID控制也具有这个缺陷。
本文设计一个基于Arduino的模糊PID直流电机调速系统,利用Arduino的多功能性,外加自适应模糊PID算法相结合,创建智能,数字化的系统来实现直流电机的高精度调速。
1.驱动电路电机在工作时候的电压和电流远高于Arduino开发板的输入输出电流电压,因此驱动电路需要通过驱动芯片来控制。
本次设计选择的驱动芯片为L298N双H 桥驱动电路控制芯片单元。
其中驱动控制芯片L298N的逻辑如下图所示,其功能逻辑通过两个端口输入共同实现。
图1-1 L298N功能逻辑图本次设计选用的L298N的芯片引脚功能设置如下:OUT1-4端口设置接入步进电机或直流电机,5脚、7脚、10脚、12脚接入控制电平,对电机进行变速、正反转等功能的控制。
而ENA和ENB分别控制电机的启停,作为控制芯片使能端来使用。
其引脚分部如图1-2所示。
基金:大学生创新创业训练项目(批准号:S202010361117)图1-2 控制芯片驱动电路引脚分布图2.控制电路基于上述原则和控制功能,结合Arduino开发板设计实现了具体的硬件电路,其设计图如图2-1所示,功能阐述如下:首先通过开发板测取电机数据到处理器中,通过提前编程的算法进行指定逻辑的分析处理过程,然后将信号返回到驱动电路上,驱动电路通过预置的控制逻辑实现相关功能。
图2-1 控制电路硬件设计图3.模糊pid控制基于上述控制逻辑和所要实现的功能目标设计模糊PID控制算法如图3-1所示。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
**************************************************************************/ void PID::SetOutputLimits(double Min, double Max) { if(Min >= Max) return; outMin = Min; outMax = Max; if(inAuto) { if(*myOutput > outMax) *myOutput = outMax; else if(*myOutput < outMin) *myOutput = outMin; if(ITerm > outMax) ITerm= outMax; else if(ITerm < outMin) ITerm= outMin; } } /* SetMode(...)**************************************************************** * Allows the controller Mode to be set to manual (0) or Automatic (non-zero) * when the transition from manual to auto occurs, the controller is * automatically initialized ******************************************************************************/ void PID::SetMode(int Mode) { bool newAuto = (Mode == AUTOMATIC); if(newAuto == !inAuto) { /*we just went from manual to auto*/ PID::Initialize(); } inAuto = newAuto; } /* Initialize()**************************************************************** * does all the things that need to happen to ensure a bumpless transfer * from manual to automatic mode. ******************************************************************************/ void PID::Initialize() { ITerm = *myOutput; lastInput = *myInput; if(ITerm > outMax) ITerm = outMax; else if(ITerm < outMin) ITerm = outMin;
******************************************************************************/ void PID::SetTunings(double Kp, double Ki, double Kd) { if (Kp<0 || Ki<0 || Kd<0) return; dispKp = Kp; dispKi = Ki; dispKd = Kd; double SampleTimeInSec = ((double)SampleTime)/1000; kp = Kp; ki = Ki * SampleTimeInSec; kd = Kd / SampleTimeInSec; if(controllerDirection ==REVERSE) { kp = (0 - kp); ki = (0 - ki); kd = (0 - kd); } } /* SetSampleTime(...) ********************************************************* * sets the period, in Milliseconds, at which the calculation is performed ******************************************************************************/ void PID::SetSampleTime(int NewSampleTime) { if (NewSampleTime > 0) { double ratio = (double)NewSampleTime / (double)SampleTime; ki *= ratio; kd /= ratio; SampleTime = (unsigned long)NewSampleTime; } } /* SetOutputLimits(...)**************************************************** * This function will be used far more often than SetInputLimits. while * the input to the controller will generally be in the 0-1023 range (which is * the default already,) the output will be a little different. maybe they'll * be doing a time window and will need 0-8000 or something. or maybe they'll * want to clamp it from 0-125. who knows. at any rate, that can all be done * here.
/* SetTunings(...)************************************************************* * This function allows the controller's dynamic performance to be adjusted. * it's called automatically from the constructor, but tunings can also * be adjusted on the fly during normal operation
/****************************************************************************** **************** * Arduino PID Library - Version 1.0.1 * by Brett Beauregard <br3ttb@> * * This Library is licensed under a GPLv3 License ******************************************************************************* ***************/ #if ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif #include <PID_v1.h> /*Constructor (...)********************************************************* * The parameters specified here are those for for which we can't set up * reliable defaults, so we need to have the user set them. ***************************************************************************/ PID::PID(double* Input, double* Output, double* Setpoint, double Kp, double Ki, double Kd, int ControllerDirection) { myOutput = Output; myInput = Input; mySetpoint = Setpoint; inAuto = false; PID::SetOutputLimits(0, 255); //default output limit corresponds to //the arduino pwm limits //default Controller Sa00; seconds PID::SetControllerDirection(ControllerDirection); PID::SetTunings(Kp, Ki, Kd); lastTime = millis()-SampleTime; }
/* Compute() ********************************************************************** * This, as they say, is where the magic happens. this function should be called * every time "void loop()" executes. the function will decide for itself whether a new * pid Output needs to be computed. returns true when the output is computed, * false when nothing has been done. ******************************************************************************* ***/ bool PID::Compute() { if(!inAuto) return false; unsigned long now = millis(); unsigned long timeChange = (now - lastTime); if(timeChange>=SampleTime) { /*Compute all the working error variables*/ double input = *myInput; double error = *mySetpoint - input; ITerm+= (ki * error); if(ITerm > outMax) ITerm= outMax; else if(ITerm < outMin) ITerm= outMin; double dInput = (input - lastInput); /*Compute PID Output*/ double output = kp * error + ITerm- kd * dInput; if(output > outMax) output = outMax; else if(output < outMin) output = outMin; *myOutput = output; /*Remember some variables for next time*/ lastInput = input; lastTime = now; return true; } else return false; }