当前位置:   article > 正文

智能车中的PID算法

智能车中的PID算法

本文章主要介绍如何用PID算法和电感使你的小车完成最简单的循迹。

需要准备的硬件:芯片ch32v103R8T6,电机驱动板,核心板,两个电机,一个舵机,四个轮子,电磁传感器,干簧管(本文罗列的硬件对型号不做要求)。

我们使用的编译软件是MounRiver Studio,使用的库是由逐飞提供的库。

我们使用干黄管来使其可以完美的停车。

下图为我们对硬件结构的一个整体思路

下图为我们智能车

下图为我们程序设计的基本思路

程序源代码如下

  1. #include "headfile.h"
  2. int16 Left_Adc1=0,Right_Adc1=0; //转换后的左右电感值
  3. int16 Left_Adc2=0,Mid_Adc=0,Right_Adc2=0;
  4. int stop=0;
  5. uint16 duty3=8000;//停车电机反转
  6. int16 duty1=0; //舵机占空比
  7. float kp,kd; //舵机pid的p d参数
  8. //误差值
  9. float error;
  10. float error_last;
  11. float error_angle; //舵机转角pd算法偏值
  12. int16 ad_value1;
  13. int16 ad_value2;
  14. //获取电感值
  15. float get_adc(void){
  16. int i,j;
  17. float ad_value[10],sum_value=0;
  18. float temp;
  19. for(i=0;i<10;i++)
  20. {
  21. ad_value1=adc_convert(ADC_IN6_A6, ADC_12BIT);
  22. ad_value2=adc_convert(ADC_IN8_B0, ADC_12BIT);
  23. //差比和算法
  24. ad_value[i]=100*(ad_value2-ad_value1)/(ad_value2+ad_value1);
  25. }
  26. //冒泡算法
  27. for(j=0;j<9;j++)
  28. {
  29. for(i=0;i<9-j;i++)
  30. {
  31. if(ad_value[i]>ad_value[i+1])
  32. {
  33. temp=ad_value[i];
  34. ad_value[i]=ad_value[i+1];
  35. ad_value[i+1]=temp;
  36. }
  37. }
  38. }
  39. for(i=1;i<9;i++){
  40. sum_value+=ad_value[i];
  41. }
  42. temp=sum_value/8;
  43. return temp;
  44. }
  45. int main(void)
  46. {
  47. //关闭总中断
  48. DisableGlobalIRQ();
  49. //务必保留,本函数用于初始化MPU 时钟 调试串口
  50. board_init();
  51. //此处编写用户代码(例如:外设初始化代码等)
  52. //lcd初始化
  53. lcd_init();
  54. //lcd_clear(WHITE);
  55. //adc初始化
  56. adc_init(ADC_IN6_A6);//中
  57. adc_init(ADC_IN8_B0);//右二
  58. //电机初始化
  59. timer_pwm_init(PWM4_CH4_B9, 12500, 0);
  60. timer_pwm_init(PWM4_CH3_B8, 12500, 0);
  61. timer_pwm_init(PWM4_CH2_B7, 12500, 0);
  62. timer_pwm_init(PWM4_CH1_B6, 12500, 0);
  63. //舵机初始化
  64. timer_pwm_init(PWM3_CH1_C6,50,740);//舵机的pwm
  65. //D2口初始化
  66. gpio_init(D2,GPI,0,IN_PULLUP);
  67. //变量初始化
  68. error=0;
  69. error_last=0;
  70. //舵机pd算法的pd值
  71. kp=1.39;//5.2 4.57
  72. kd=0.02551; //1 1.15 1.55
  73. //总中断最后开启
  74. EnableGlobalIRQ(0);
  75. while(1)
  76. {
  77. error_last=error;
  78. error=get_adc();
  79. error_angle=kp*error+kd*(error-error_last);//舵机pd算法确定转角偏值
  80. duty1=740-(int16)error_angle;
  81. //舵机限幅
  82. if(duty1>=796)
  83. duty1=796;
  84. else if(duty1<=662)
  85. duty1=662;
  86. timer_pwm_duty(PWM3_CH1_C6,duty1);
  87. if(stop<=2)
  88. {
  89. //电机
  90. timer_pwm_duty(PWM4_CH3_B8,1500);//开关这边电机正转
  91. //timer_pwm_duty(PWM4_CH4_B9, 1800);//开关这边电机反转
  92. timer_pwm_duty(PWM4_CH2_B7,1850);//非正转
  93. //timer_pwm_duty(PWM4_CH1_B6,1800);//非反转
  94. }
  95. //干簧管停车
  96. if(gpio_get(D2)==0)
  97. {
  98. stop++;
  99. systick_delay_ms(100);
  100. }
  101. if(stop>2)
  102. {
  103. timer_pwm_duty(PWM3_CH1_C6,740);//992
  104. timer_pwm_duty(PWM4_CH4_B9,duty3);//开关这边电机
  105. timer_pwm_duty(PWM4_CH2_B7,0);
  106. timer_pwm_duty(PWM4_CH3_B8,0);//非开关这边电机
  107. timer_pwm_duty(PWM4_CH1_B6,duty3);
  108. systick_delay_ms(100);
  109. while(1){
  110. //电机反转实现停车
  111. timer_pwm_duty(PWM4_CH4_B9,0);//开关这边电机
  112. timer_pwm_duty(PWM4_CH2_B7,0);
  113. timer_pwm_duty(PWM4_CH3_B8,0);//非开关这边电机
  114. timer_pwm_duty(PWM4_CH1_B6,0);
  115. }
  116. }
  117. //lcd显示
  118. lcd_showstr(1, 0, "Left_Adc1");
  119. lcd_showint16(80,0, Left_Adc1);
  120. lcd_showstr(2, 1, "Left_Adc2");
  121. lcd_showint16(80, 1, Left_Adc2);
  122. lcd_showstr(3, 2, "L1");//左电感 A6
  123. lcd_showint16(80,2, ad_value1);
  124. lcd_showstr(4, 3, "Right_Adc1");
  125. lcd_showint16(90,3, Right_Adc1);
  126. lcd_showstr(5, 4, "R2");//右电感 B0
  127. lcd_showint16(90, 4, ad_value2);
  128. lcd_showint32(1, 5, duty1,4);
  129. }
  130. }

由于电感的接口不同,可能电感的初始化不同。

本人建议自己画电路板和驱动板,避免出现一些小问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/961069
推荐阅读
相关标签
  

闽ICP备14008679号