这是经过给队友讲解串级PID的程序的之后的进一步的理解总结。
内环的实际值,取决于你能测出什么值给内环。而内环的输入就是内环误差
内环的输出值,是内环误差(内环目标值-内环实际值)经过内环pid计算后的值(可加 死区,不要积分项,要微分项)
其上限值需要考虑执行器所能控制的极限
内环的目标值,同时也是外环的输出值。
外环控制对象是内环控制对象的积分,所以PID参数整定也是结合现象,用控制变量法先整定内环,后整定外环。
外环的实际值,取决与你能测出什么值给外环。而外环的输入就是外环误差。它对应是串级PID最终要控制的物理量。
外环的输出值,是外环误差(外环目标值-外环实际值)经过外环pid计算后的值。(可加入 死区 和 积分分离,不要微分项)。
其上限值需要考虑对应物理量,估算出合理值。
外环的目标值,对应串级pid控制要达成的控制效果。
在条件允许时: 传感器获取数据时 加入 滤波算法 ;执行器在输出控制时 加入 平滑输出算法
以板球控制串级PID控制为例: (位置环不加死区,效果反而更好,不用担心板子不平)
通过串口控制两个电机
改自野火的例程,可以通过串口调试助手直接控制两个电机的速度和转向。
移植后关键函数:放在stm32f1xx_it.c 的串口中断服务函数;放在control.c的deal_serial_data()函数;放在bsp_debug.c的串口重定之类的函数。
(上述程序是没有真正编写协议的,没有解码数据帧之类的操作)
有协议的要参考之前的上位机设置PID的程序:
其中bsp_debug.c里的串口回显可以让上位机确认下位机是否成功接收到控制信号,之后给上位机控制程序的时候记得编写相应代码利用下位机的串口回显,保证控制的可靠性。
之后可以根据上述两个函数将小车由电脑通过USB线控制,改成可以通过蓝牙、wifi等无线来控制小车。
MPU6050获取平衡车姿态
由于MPU6050的安装姿态与小车姿态不匹配,得把横滚角roll和偏航角pitch 转换一下。
加速度计和陀螺仪的数据都要变换。
实际测式最高读取速率:调用这个函数的时间可以在0.5ms至300ms,太快的话可能DMP还没处理完数据。 即最高读取频率可达2KHz(文件上说1KHz)。实际用的时候还是1ms以上调用一次稳妥一些
移植的时候记得把 mpu6050.c inv_mpu.c inv_mpu_dmp_motion_driver.c 都添加到工程中,然后要调用相关函数的时候,把mpu6050.h 和 inv_mpu.h这两个头文件include就行
自制平衡车PID算法程序设计
喵呜两轮平衡车没有使用速度闭环内环的PID控制,它通常三轮,四轮的小车上的。
两轮平衡车上的速度环 、角度环是分别各自去运算之后合成出一个输出。
速度环输入:电机编码器捕获到的脉冲数
回看之前自己照着喵呜的教程写的HAL库的平衡小车代码,发现用来存放编码器值的变量竟然是unsigned int 类型的变量,可是之前还让小车立起来了。。。。。。(得去比对一下之前的程序,查找原因)
去看喵呜的标准库的例程,它存放编码器值的变量是short类型的。
角度环输入: 有软件解算和硬件解算两种,因为滤波算法接触的不多,所以直接用mpu6050硬件解算出来的数据更靠谱。
软件解算姿态:MPU6050获取的一个方向的角度数据(accx或accy)和一个方向的加速度数据(gyrox或gyroy) 经过互补滤波之后的值(当成角度来理解就行)。
(喵呜用了一种很简单的互补滤波算法,可能是为了为了避免移植mpu6050的DMP驱动库的繁琐操作,不一定可靠。)
DMP解算姿态:直接用mpu6050硬件解算出来的欧拉角中的一个角度值