2218| 1
|
【自制无人机】“辛”路历程(八)PID控制 |
【自制无人机】“辛”路历程(八) 【前言】 无人机飞控,绕不开的PID控制。 PID 控制是自动化控制领域应用非常广的控制方式,P 代表比例,I 代表积分,D 代表微分,从这些名词中可以看出,PID 控制是基于数学中一项重要的分支:微积分学为基础的数字化自动控制方式,它以传感器采集的数据作为输入源,按预定的 PID 参数根据特定的公式计算以后输出控制。 测试PID测距控制专用小车 过多的也不说了,网络相关内容,十分丰富。 1、下面的这个帖讲的如题目“通俗易懂”,非常适合新手。 Arduino菜鸟通俗版解读系列(10)PID控制(上) 可惜我没有找到(下),也许作者就没写。 2、下面的这个帖子,除火车到站这个例,还举了水缸加水的栗子。 PID简单理论分析(实例分析) 3、PID库 使用PID库,轻松搞定PID(上) 【测试一】 使用超声波PID算法测距控制。 1、调试超声波 超声波使用DFrobotGravity:URM09-模拟量超声波测距传感器 使用文档 [mw_shl_code=java,false]// # Editor : roker // # Date : 18.02.2019 // # Product name: URM09 Ultrasonic Sensor(Gravity Analog)(V1.0) // # Product SKU : SEN0307 // # Version : 1.0 #define MAX_RANG (520)//模块测距极值为520cm(比有效最大量程值略大) #define ADC_SOLUTION (1023.0)//Arduino UNO 的ADC精度为10bit int sensityPin = A0; // select the input pin void setup() { // Serial init Serial.begin(9600); } float dist_t, sensity_t; void loop() { // read the value from the sensor: sensity_t = analogRead(sensityPin); // turn the ledPin on dist_t = sensity_t * MAX_RANG / ADC_SOLUTION;// Serial.print(dist_t,0); Serial.println("cm"); delay(500); }[/mw_shl_code] 【测试二】 PID测距控制,专门为了这个测试制作了一个小车,采用单电机控制,超声波测距,PID算法控制到指定距离。 [mw_shl_code=java,false]#define MAX_RANG (520)//模块测距极值为520cm(比有效最大量程值略大) #define ADC_SOLUTION (1023.0)//Arduino UNO 的ADC精度为10bit int sensityPin = A0; int input1 = 5; // pin 5 向 input1 输出 int input2 = 6; // pin 6 向 input2 输出 int enA = 10; //pin 10 向 输出A使能端输出 unsigned long lastTime; double Input, Output, Setpoint; double errSum, lastErr; double kp, ki, kd; void Compute() { /*How long since we last calculated*/ unsigned long now = millis(); double timeChange = (double)(now - lastTime); /*Compute all the working error variables*/ double error = Setpoint - Input; if(error<0){ errSum += (error * timeChange); double dErr = (error - lastErr) / timeChange; /*Compute PID Output*/ Output = kp * error + ki * errSum + kd * dErr; /*Remember some variables for next time*/ lastErr = error; lastTime = now; } else { Output =45; } } void SetTunings(double Kp, double Ki, double Kd) { kp = Kp; ki = Ki; kd = Kd; } void setup() { // Serial init Serial.begin(9600); pinMode(input1,OUTPUT); pinMode(input2,OUTPUT); pinMode(enA,OUTPUT); Setpoint=30; SetTunings(2, 0.001, 0.01); } float dist_t, sensity_t; void loop() { // read the value from the sensor: sensity_t = analogRead(sensityPin); // turn the ledPin on dist_t = sensity_t * MAX_RANG / ADC_SOLUTION;// Input=dist_t; /*Serial.print(dist_t,0);*/ Compute(); digitalWrite(input1,HIGH); //给高电平 digitalWrite(input2,LOW); //给低电平 if(45-Output>254){ analogWrite(enA,254); } else{ analogWrite(enA,45-Output); } Serial.println(Output,0); delay(50); }[/mw_shl_code] 测试视频 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed