无人机定高算法

高度控制:高于目标值时应该减速,要输出负值,所以高度差=目标高度-当前高度

速度控制:向上时(速度为正)应该减速,要输出负值,所以速度差=高度差的速度-当前速度

如果只有高度控制时:出现高度变化时,高度差要么是正数要么是负数。即使高度差会慢慢变小,但是高度差在没有有到达目标高度时,高度差的符号是不会变的,符号不变就一直加速,尽管加速度在变小,有加速就一定会越过目标值。越过目标值才会开始减速。在减速开始的瞬间,就意味着已经过越过目标点。高度差又出现了,再次重复上面的过程。所以不管怎么调PID参数,都不可能稳定高度。

那么要稳定高度,就必须要到达目标高度之前,输出反向的力刹住。

重新分析高度差控制的环节会发现,到回到目标高的时候,输出减少到最小值了,但是因为是一直加速度回来,所以速度也达到到了最大值。那么就可以利用此时的速度来做刹车了。所以有了下面的速度控制。

如果只有速度控制器时:出现向上的速度时,输出负值,抵制加速,出现向下的速度时,输出正值,上升回来。那么高度控制实际上就是对速度的控制.

然而只有速度控制的话,由于高度计的精度就在那,微小的速度变化是检测不出来的。那么在缓慢下降和上升时就没办法调节了。

所以前面的高度差就有作用了,高度差作为微调添加到速度那边去计算。就算速度为0时,由于高度差的存在,输出也不会为0。直到高度差和速度都为0时才不输出。

现在思路就很清晰了,速度作为动态快速响应,高度作为微调校正。所以速度为主,高度为辅助,作为微调的高度差的PID的输出绝对不能越过速度。这么看的话高度环只有比例一个调节也可以了。

算法有了,剩下的问题是速度和高度怎么测量,用什么传感器了。

typedef struct {
	float kp;
	float ki;
	float kd;
	float max;
	float min;
	float error;
	float integral;
	float differential;
	float maxIntegral;
	float minIntegral;
	float lastError;
	float lastInput;
}PID_InitTypedef;
long CONSTRAIN(long input, long min, long max)
{
	if (input < min)
		input = min;
	if (input > max)
		input = max;
	return input;
}
float PID_ComputeInt(float error, PID_InitTypedefInt16* pid)
{

	pid->error = error;
	pid->integral += pid->error;
	pid->integral = CONSTRAIN(pid->integral, pid->minIntegral, pid->maxIntegral);
	pid->differential = pid->error - pid->lastError;
	//pid->lastInput = input;
	pid->lastError = pid->error;
	float result = pid->kp * pid->error + pid->ki * pid->integral/1000 + pid->kd * pid->differential;
	result = CONSTRAIN(result, pid->min, pid->max);
	return result;
}

/*定高串级PID计算*/
/*mesurement:测量到的高度数据*/
/*targetPoint:目标高度*/
/*_pidH:高度环PID*/
/*_pidV:速度环PID*/
/*Output: 速度*/
/*timestamp: 时间戳(us)*/
float KeepHeight(float mesurementHeight, float targetHeight, PID_InitTypedef* _pidH, PID_InitTypedef *_pidV, uint32_t timestamp)
{
	static float velocity;//高度的变化速度,
	static float velocityPre;//上次高度的变化速度,
	static float mesurementPre;//上次的高度
	static float result;
	static float resultPre;
	static float timestampPre;//上次时间戳
	float outH, outV;//高度度环输出,速度环输出
	float dt;//时间差,us
	dt = timestamp - timestampPre;//时间差,us
	timestampPre = timestamp;
	velocity = mesurementHeight - mesurementPre;//计算测量值的变化量,即速度
	velocity = velocity * 1000000.0f/ dt;//实际速度cm/s
	velocity = constrain(velocity, -1500, 1500);// 限制  velocity ±1500cm/s
	velocity = velocity * 0.2 + velocityPre * 0.8;//滤波一下
	velocityPre = velocity;
	mesurementPre = mesurementHeight;
	outH = PID_Compute(targetHeight - mesurementHeight, _pidH);//如果存在高度差,则会输出速度
	outV = PID_Compute(outH - velocity, _pidH);//达到上面的速度
	result += outV;//输出是调节值,要稳定输出则要累计。位置型PID
	result = constrainf(result, 1000, 2000);//限制输出范围
	result = result * 0.1 + resultPre * 0.9;//输出滤波,限制突变
	resultPre = result;
	return result;
}

高度计用是的歌尔的SPL06,加速度计是MPU6050,看看定高效果

### 无人机飞控 PID 控制代码示例 以下是基于 MATLAB 的无人机动力学仿真建模与姿态控制中的 PID 控制器实现方法[^1]: ```matlab % 义PID参数 Kp = 0.8; % 比例增益 Ki = 0.2; % 积分增益 Kd = 0.5; % 微分增益 % 初始化变量 error_prev = 0; integral = 0; % 姿态角目标值(单位:度) theta_target = 10; % 时间步长 dt = 0.01; % 模拟飞行时间 t_end = 10; time = 0:dt:t_end; % 存储数据用于绘图 theta_history = zeros(size(time)); control_signal_history = zeros(size(time)); for i = 1:length(time) % 当前时刻的姿态角(假设来自传感器读数) theta_current = sin(2*pi*time(i)/t_end)*5; % 示例正弦波输入 % 计算误差 error = theta_target - theta_current; % 更新积分项 integral = integral + error * dt; % 计算微分项 derivative = (error - error_prev) / dt; % PID控制律计算 control_signal = Kp*error + Ki*integral + Kd*derivative; % 更新历史记录 theta_history(i) = theta_current; control_signal_history(i) = control_signal; % 更新上一时刻的误差 error_prev = error; end % 绘图显示结果 figure; subplot(2,1,1); plot(time, theta_history); title('当前姿态角随时间变化'); xlabel('时间(s)'); ylabel('角度(°)'); subplot(2,1,2); plot(time, control_signal_history); title('控制信号随时间变化'); xlabel('时间(s)'); ylabel('控制量'); ``` 上述代码展示了如何利用 PID 控制算法调整无人机的姿态角。其中,`Kp`, `Ki`, 和 `Kd` 是可调的比例、积分和微分系数。 对于嵌入式系统的 C 实现,可以参考以下伪代码结构[^2]: ```c // PID控制器函数义 void PIDControl() { static float prev_error = 0.0f; static float integral = 0.0f; const float kp = 0.8f; // 比例增益 const float ki = 0.2f; // 积分增益 const float kd = 0.5f; // 微分增益 float current_theta = GetSensorData(); // 获取当前姿态角 float target_theta = 10.0f; // 设的目标姿态角 float error = target_theta - current_theta; // 防止积分饱和 integral += error; if (integral > MAX_INTEGRAL_LIMIT) { integral = MAX_INTEGRAL_LIMIT; } else if (integral < MIN_INTEGRAL_LIMIT) { integral = MIN_INTEGRAL_LIMIT; } // 计算PID输出 float pid_output = kp * error + ki * integral + kd * (error - prev_error); // 设置电机PWM占空比或其他执行机构指令 SetMotorPWM(pid_output); // 更新上次误差 prev_error = error; } ``` 此代码片段展示了一个简单的 PID 控制逻辑,适用于实时控制系统中对无人机姿态的调节。 #### 初始化配置的重要性 在实际开发过程中,在进入主循环之前需要完成一系列初始化操作,例如串口通信设置、传感器校准以及电机驱动初始化等[^3]。这些步骤确保了整个系统能够正常运行并提供精确的数据支持给后续的控制算法
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值