float Velocity(float encoder) { static float Encoder, Encoder_Integral; float Velocity_PWM, Encoder_Least; Encoder_Least = encoder; //速度滤波 Encoder *= 0.7; //一阶低通滤波器 Encoder += Encoder_Least*0.3; //一阶低通滤波器 Encoder_Integral += Encoder; //积分出位移 if(Encoder_Integral > +200) Encoder_Integral = +200; //积分限幅 if(Encoder_Integral < -200) Encoder_Integral = -200; //积分限幅 Velocity_PWM = KP * Encoder + KI/100 * Encoder_Integral;//获取最终数值 return Velocity_PWM; }
时间: 2024-02-14 20:31:24 浏览: 88
这段代码是一个计算速度的函数。它使用一个编码器的值作为输入,并返回计算得到的速度值。
以下是代码的解释:
- 静态变量 `Encoder` 和 `Encoder_Integral` 用于在函数调用之间保持状态。
- `Encoder_Least` 是输入的编码器值,用于进行速度滤波。
- `Encoder` 变量通过一阶低通滤波器进行更新,以平滑输入值。
- `Encoder_Integral` 是用于积分计算位移的变量。
- 如果 `Encoder_Integral` 超过 +200 或小于 -200,会进行积分限幅。
- `Velocity_PWM` 是根据编码器和编码器积分值计算得到的最终速度值,使用了一些系数 KP 和 KI。
请注意,代码中未提供 KP 和 KI 的具体值,您需要根据实际需求设置这些系数。
相关问题
/*************************************************************************** 函数功能:电机的闭环控制 入口参数:电机的编码器值 返回值 :电机的PWM ***************************************************************************/ int Velocity_A(int encoderA) { static float velocity,Encoder_Least,Encoder_bias; static float Encoder_Integral; //================速度PI控制器=====================// Encoder_Least =200-encoderA; //获取最新速度偏差=目标速度-测量速度 Encoder_bias *= 0.84; //一阶低通滤波器 Encoder_bias += Encoder_Least*0.16; //一阶低通滤波器,减缓速度变化 Encoder_Integral +=Encoder_bias; //积分出位移 积分时间:10ms if(Encoder_Integral>380000) Encoder_Integral=380000; //积分限幅 if(Encoder_Integral<-380000) Encoder_Integral=-380000; //积分限幅 velocity=Encoder_bias*20+Encoder_Integral*0.5; //速度控制 return velocity; }
这是一个用于电机闭环控制的函数。函数的入口参数是电机的编码器值,函数将根据编码器值计算出电机的PWM值,并作为返回值。函数内部使用了速度PI控制器来实现闭环控制。
函数首先定义了一些静态变量,包括velocity(速度)、Encoder_Least(速度偏差)、Encoder_bias(低通滤波后的速度偏差)和Encoder_Integral(速度偏差的积分)。
接下来,函数使用速度PI控制器的算法进行计算。首先获取最新的速度偏差,即目标速度减去测量速度。然后通过一阶低通滤波器对速度偏差进行平滑处理,减缓速度变化。接着将平滑后的速度偏差累积到积分器中,并对积分器进行限幅处理,避免积分器过大或过小。
最后,根据速度偏差和积分项的加权求和,得到电机的PWM值,即控制电机转动的信号。函数将该PWM值作为返回值。
请注意,该函数中使用的一些参数和权重是固定的,您可能需要根据具体情况进行调整和优化。
解释以下代码:void EXTI9_5_IRQHandler(void) { int PWM_out; if(EXTI_GetITStatus(EXTI_Line5)!=0) { if(PBin(5) == 0) { EXTI_ClearITPendingBit(EXTI_Line5); Encoder_Left = -Read_Spead(2); //采集编码器速度 Encoder_Right = Read_Spead(3); measure = (Encoder_Left + Encoder_Right); //将编码器速度给测量值 mpu_dmp_get_data(&Pitch, &Roll, &Yaw); //角度 MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //角速度 // Velocity_out = Velocity_PI(measure); //速度环计算 Turn_out = Turn(gyroz); // Vertical_out = Vertical_PI(gyroz); PWM_out = Velocity_out; //PWM输出 motor1 = PWM_out + Turn_out - Vertical_out; motor2 = PWM_out - Turn_out + Vertical_out; Limit(&motor1, &motor2); //PWM限幅 SETPWM(motor1,motor2); //加载PWM到电机 } } }
这段代码是一个中断处理函数,当外部中断发生时会被调用。该函数执行以下操作:
1. 检查外部中断线5是否被触发,如果是则执行以下操作:
2. 检查PBin(5)引脚的状态是否为低电平,如果是则执行以下操作:
3. 清除外部中断线5的中断标志位。
4. 读取编码器的速度,并将左右编码器速度相加得到测量值。
5. 通过调用mpu_dmp_get_data函数获取当前的俯仰角(Pitch)、横滚角(Roll)和偏航角(Yaw)。
6. 通过调用MPU_Get_Gyroscope函数获取当前的角速度。
7. 通过调用Turn函数计算转向控制输出。
8. 计算速度控制输出,并将其赋值给PWM_out变量。
9. 计算垂直方向控制输出,并将其赋值给Vertical_out变量。
10. 计算左右电机的PWM输出,并将其限幅在合理范围内。
11. 将计算得到的PWM输出加载到电机进行控制。
值得注意的是,该函数调用了一些其他的函数,如Turn函数、mpu_dmp_get_data函数和MPU_Get_Gyroscope函数等,这些函数的具体实现细节需要查看其它代码文件。
阅读全文