请问Pixhawk是比较好的开源飞控板了吧?是否支持自己编写飞控代码?还是指支持PID调参而已呢?

请问Pixhawk是比较好的开源飞控板了吧?是否支持自己编写飞控代码?还是指支持PID调参而已呢?,第1张

apm系列里顶级的了。

里面预置了PID的飞控程序,可以只调参就能飞,

但作为开源飞控,当然也可以自己编程。此缺

性能做一般的飞控肯定够用,其实性能跟你写算法的能力也相关。

详细的东西,仔掘你可以去相关论坛里逛逛问问。森戚辩

BTW:你是Michael Dou·bi?

刚好前不久搞过PID,部分程序如下,仅供参考

/*==============================================================================

在使用单片机作为控制cpu时,请稍作简化,具体的PID参数必须由具体对象通过实验确定。

由于单片机的处理速度和ram资源的限制,一般不采用浮点数运算,而将所有参数全部用整数,

运算到最后再除以一个2的N次方数据(相当于移位),作类似定点数运算,可大大提高运算速度,

根据控制精度的不同要求,当精度要求穗者雹很高时,注意保留移位引起的“余数”,做好余数补偿。猜帆

这个程序只是一般常用pid算法的基本架构,没有包含输入输出处理部分。

==============================================================================*/

#include <string.h>

#include <stdio.h>

/嫌衡*===============================================================================

PID Function

The PID function is used in mainly

control applications. PID Calc performs one iteration of the PID

algorithm.

While the PID function works, main is just a dummy program showing

a typical usage.

PID功能

在PID功能主要用于控制应用。 PID 计算器执行一个PID的迭代算法。虽然PID功能的工程,

主要只是一个虚拟程序显示一个典型的使用。

================================================================================*/

typedef struct PID {

double SetPoint // 设定目标 Desired Value

double Proportion// 比例常数 Proportional Const

double Integral // 积分常数 Integral Const

double Derivative// 微分常数 Derivative Const

double LastError // Error[-1]

double PrevError // Error[-2]

double SumError // Sums of Errors

} PID

/*================================ PID计算部分===============================*/

double PIDCalc( PID *pp, double NextPoint )

{

double dError,Error

Error = pp->SetPoint - NextPoint // 偏差

pp->SumError += Error // 积分

dError = pp->LastError - pp->PrevError// 当前微分

pp->PrevError = pp->LastError

pp->LastError = Error

return (pp->Proportion * Error // 比例项

+ pp->Integral * pp->SumError // 积分项

+ pp->Derivative * dError // 微分项

)

}

/*======================= 初始化的PID结构 Initialize PID Structure===========================*/

void PIDInit (PID *pp)

{

memset ( pp,0,sizeof(PID))

}

/*======================= 主程序 Main Program=======================================*/

double sensor (void)// 虚拟传感器功能 Dummy Sensor Function{return 100.0}

void actuator(double rDelta)// 虚拟驱动器功能 Dummy Actuator Function{}

void main(void)

{

PID sPID // PID控制结构 PID Control Structure

double rOut // PID响应(输出) PID Response (Output)

double rIn // PID反馈(输入) PID Feedback (Input)

PIDInit ( &sPID ) // 初始化结构 Initialize Structure

sPID.Proportion = 0.5 // 设置PID系数 Set PID Coefficients

sPID.Integral = 0.5

sPID.Derivative = 0.0

sPID.SetPoint = 100.0 // 设置PID设定 Set PID Setpoint

for ()

{ // 模拟最多的PID处理 Mock Up of PID Processing

rIn = sensor () // 读取输入 Read Input

rOut = PIDCalc ( &sPID,rIn ) // 执行的PID迭代 Perform PID Interation

actuator ( rOut ) // 所需的更改的影响 Effect Needed Changes

}

/***********************************************************************

PID温度控制程序

程序说明:

系统上电后显示 “--温度”

表示需要先设定温度才开始进行温度检测

温度设定完毕后程序才开始进行PID温控

***********************************************************************/

#include <reg52.h>

#include <absacc.h>

#include"DS18B20.H"

#include"PID.H"

#define uchar unsigned char

#define uint unsigned int

unsigned char code tab[]=

{

0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF

}

/*个位0~9的数码管段码*/

unsigned char code sao[]=

{

0x7f,0xbf,0xdf,0xef

}

//扫描码

uchar set=30,keyflag=1 //set初谈腊段始化为30° keyflag为进入温度设定的标志位

//4个按键使用说明

sbit key_out=P1^0 //用于温度设定后的退出

sbit key_up=P1^1 //设定温度含誉加

sbit key_down=P1^2 //设定温度减

sbit key_in=P1^3 //在程序的运行中如需要重新设定温度 按下此键才能进入设置模式并且此时是停在温度控制的,按下key_out键后才表示设定完毕

void Show_key()

/***********************************************************/

void delays(unsigned char k)

{

unsigned char i,j

for(i=0i<ki++)

for(j=0j<50j++)

}

/*********************************************************

//数码管显示函数

P0口 作为数据口

P2口的低四位作为扫描口

变量 x表示扫描

d表示是否要加小数点 为1是 为0不加

y表示传递的数值

*********************************************************/

LCD_disp_char(uchar x,bit d,uchar y)

{

P2=0XFF

P0=0xFF

if(d==0)

P0=tab[y]

else

P0=tab[y]&0x7f //与上0x7f表示是否要加小数点

P2=sao[x]//打开扫描端号

}

/*********************************************************

按键扫描

*********************************************************/

void keyscan(void)

{

if(key_in==0) //按键进入函数

{

delays(10) //延时消抖 (以下同)

if(key_in==0)

{

while(key_in==0)

{

Show_key()//如果局缺一直按着键不放 就一直显示在当前状态 (以下同)

}

keyflag=1 //按键标志位

}

}

/***********************/

if(key_out==0) //按键退出

{

delays(10)

if(key_out==0)

{

while(key_out==0)

{

Show_key()

}

keyflag=0

set_temper=set

}

}

/*************************/

if(key_up==0) //设定温度的加

{

delays(10)

if(key_up==0)

{

while(key_up==0)

{

Show_key()

}

if(keyflag==1)

{

set++

if(set>90) //如果大于90°就不在加

set=90

}

}

}

/*************************/

if(key_down==0) //温度设定的减

{

delays(10)

if(key_down==0)

{

while(key_down==0)

{

Show_key()

}

if(keyflag==1)

{

set--

if(set<30) //温度减到30°时不在往下减

set=30

}

}

}

}

/*********************************************************************

按键按下时的显示函数

***********************************************************************/

void Show_key()

{

output=1

LCD_disp_char(3,0,10)//显示 -

delays(3)

LCD_disp_char(2,0,10)//显示- (表示温度设定 )

delays(3)

LCD_disp_char(1,0,set/10)//显示温度十位

delays(3)

LCD_disp_char(0,0,set%10)//显示温度个位

delays(3)

}

/*****************************************************************/

void main()

{

unsigned int tmp //声明温度中间变量

unsigned char counter=0

PIDBEGIN()//PID参数的初始化

output=1 //关闭继电器输出

while(1)

{

keyscan()

if(keyflag)

{

Show_key()//显示温度设定

}

else

{

if(counter--==0)

{

tmp=ReadTemperature()//每隔一段时间读取温度值

counter=20

}

LCD_disp_char(3,0,tmp/1000) //显示温度十位

delays(3)

LCD_disp_char(2,1,tmp/100%10)//显示温度个位

//显示小数点

delays(3)

LCD_disp_char(1,0,tmp/10%10)//显示温度小数后一位

delays(3)

LCD_disp_char(0,0,tmp%10)//显示温度小数后二位

delays(3)

P2=0XFF

P0=0xff

compare_temper()//比较温度

}

}

}

/**********************************************************************************************************************************************/

//PID算法温控C语言2008-08-17 18:58

#ifndef _PID_H__

#define _PID_H__

#include<intrins.h>

#include<math.h>

#include<string.h>

struct PID

{

unsigned int SetPoint

// 设定目标 Desired Value

unsigned int Proportion

// 比例常数 Proportional Const

unsigned int Integral

// 积分常数 Integral Const

unsigned int Derivative

// 微分常数 Derivative Const

unsigned int LastError

// Error[-1]

unsigned int PrevError

// Error[-2]

unsigned int SumError

// Sums of Errors

}

struct PID spid

// PID Control Structure

unsigned int rout

// PID Response (Output)

unsigned int rin

// PID Feedback (Input)

sbit output=P1^4

unsigned char high_time,low_time,count=0

//占空比调节参数

unsigned char set_temper

void PIDInit(struct PID*pp)

{

memset(pp,0,sizeof(struct PID))//PID参数初始化全部设置为0

}

unsigned int PIDCalc(struct PID*pp,unsigned int NextPoint)

{

unsigned int dError,Error

Error=pp->SetPoint-NextPoint

// 偏差

pp->SumError+=Error

// 积分

dError=pp->LastError-pp->PrevError

// 当前微分

pp->PrevError=pp->LastError

pp->LastError=Error

//比例

//积分项

return(pp->Proportion*Error+pp->Integral*pp->SumError+pp->Derivative*dError)

// 微分项

}

/***********************************************************

温度比较处理子程序

***********************************************************/

void compare_temper()

{

unsigned char i

//EA=0

if(set_temper>temper)

{

if(set_temper-temper>1)

{

high_time=100 //大于1°不进行PID运算

low_time=0

}

else

{ //在1°范围内进行PID运算

for(i=0i<10i++)

{

//get_temper()

rin=s

// Read Input

rout=PIDCalc(&spid,rin)//执行PID运算

// Perform PID Interation

}

if(high_time<=100) //限制最大值

high_time=(unsigned char)(rout/800)

else

high_time=100

low_time=(100-high_time)

}

}

/****************************************/

else if(set_temper<=temper) //当实际温度大于设置温度时

{

if(temper-set_temper>0)//如果实际温度大于设定温度

{

high_time=0

low_time=100

}

else

{

for(i=0i<10i++)

{

//get_temper()

rin=s

// Read Input

rout=PIDCalc(&spid,rin)

// Perform PID Interation

}

if(high_time<100) //此变量是无符号字符型

high_time=(unsigned char)(rout/10000)

else

high_time=0 //限制不输出负值

low_time=(100-high_time)

//EA=1

}

}

}

/*****************************************************

T0中断服务子程序,用于控制电平的翻转 ,40us*100=4ms周期

******************************************************/

void serve_T0()interrupt 1 using 1

{

if(++count<=(high_time))

output=0

else if(count<=100)

{

output=1

}

else

count=0

TH0=0x2f

TL0=0xe0

}

void PIDBEGIN()

{

TMOD=0x01

TH0=0x2f

TL0=0x40

EA=1

ET0=1

TR0=1

high_time=50

low_time=50

PIDInit(&spid)

// Initialize Structure

spid.Proportion=10

// Set PID Coefficients

spid.Integral=8

spid.Derivative=6

spid.SetPoint=100

// Set PID Setpoint

}

#endif

转自他人程序。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12474791.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存