当前位置:   article > 正文

MSP430F5529循迹小车 2022电赛 C题_msp430寻迹小车

msp430寻迹小车

编辑时间2022/8/21

方案

选用材料:主控MSP430F5529、直流减速电机(带光电编码器)、TB6612电机驱动、超声波测距、灰度传感器、无线透传、OLED屏显示。

使用灰度传感器巡线,超声波检测前后车距作为位置环反馈,通过位置环调节前后车距离。

关键词:MSP430   循迹    无线串口透传通信   PID算法    陀螺仪

一、题目

 

 

二、控制方案

题目难点在于小车路过“y”路口时的判断,以及小车停车时需保证20cm的间距。我们最初的想法是通过陀螺仪直线矫正通过“y”路口,实际测试发现小车直线稳定性良好,但是陀螺仪数据反馈会有跳变,经过PID直线矫正后可能会导致小车偏离赛道。经过讨论后我们决定采用检测灰度传感器数字量判断小车位置,当小车行驶“y”路口时关闭靠左一路灰度值的传入,通过路口后重新开启,该方案实际测试没有发现较大误差。

题目中均要求一车停止后二车需立即停止并保证20cm间距,所以控制方案尤为重要,我们的想法是二车使用位置环-速度环串级PID控制,这样在一车保证速度的同时,二车会紧跟一车,在一车停止后,二车会立即停止。

问题一分析

问题一较为简单,一车二车设置一样的速度后跑一圈停止即可.

问题二分析

问题二要求二车在E路径上跑两圈后追上 一车,该问中需使用位置环-速度环控制二车,一车速度调到问题二要求的速度即可。

问题三分析

问题三要求小车行驶一圈检测“等停指示”后两辆车需同时停止,与第一问差别不大,唯一区别就是速度,在保证速度的同时又要考虑行车循迹的稳定性才是关键。

问题四分析

问题四需要对小车进行路径规划,一车二车之间需要将自身的编码器里程发送接收,通过里程判断是否需要加减速。

 电赛准备的TB6612电机驱动板,画了两板,可直接连接电机。模块自带16-5V降压

链接; TB6612FNG编码电机控制 - 嘉立创EDA开源硬件平台 (oshwhub.com)

 三、代码讲解

1、小车PID代码讲解 

  1. void PID_Position_Calc( PID *pp, float CurrentPoint, float NextPoint ) //位置环
  2. {
  3. pp->Error = NextPoint - CurrentPoint;
  4. pp->SumError += pp->Error;
  5. pp->DError = pp->Error - pp->LastError;
  6. pp->output = pp->Proportion * pp->Error + \
  7. abs_limit(pp->Integral * pp->SumError, pp->Integralmax ) + \
  8. pp->Derivative * pp->DError ;
  9. if(pp->output > pp->outputmax ) pp->output = pp->outputmax;
  10. if(pp->output < - pp->outputmax ) pp->output = -pp->outputmax;
  11. // pp->PrevError = pp->LastError;
  12. pp->LastError = pp->Error;
  13. }
  14. void PID_Incremental_Calc( PID *pp, float CurrentPoint, float NextPoint ) //速度环
  15. {
  16. pp->Error = NextPoint - CurrentPoint;
  17. pp->SumError += pp->Error;
  18. pp->DError = pp->Error - pp->LastError;
  19. pp->output += pp->Proportion * ( pp->Error - pp->LastError )+ \
  20. abs_limit(pp->Integral * pp->Error, pp->Integralmax ) + \
  21. pp->Derivative * ( pp->Error + pp->PrevError - 2*pp->LastError);
  22. if(pp->output > pp->outputmax ) pp->output = pp->outputmax;
  23. if(pp->output < - pp->outputmax ) pp->output = -pp->outputmax;
  24. pp->PrevError = pp->LastError;
  25. pp->LastError = pp->Error;
  26. }
  27. void PIDInit(PID *pp, float Kp , float Ki , float Kd , float outputmax, float Integralmax) //PID初始化
  28. {
  29. pp->Integralmax = Integralmax;
  30. pp->outputmax = outputmax;
  31. pp->Proportion = Kp;
  32. pp->Integral = Ki;
  33. pp->Derivative = Kd;
  34. pp->DError = pp->Error = pp->output = pp->LastError = pp->PrevError = 0;
  35. }
  1. void navigation_execute(float angle_z,int16_t left_sp,int16_t right_sp)//正反馈 陀螺仪直线矫正
  2. {
  3. // uint8_t angle_dev = 2;
  4. // if(mpu_angle>(angle_z-3))
  5. // moto_set_speed(gpt_cnt.set_speed_a+angle_dev,gpt_cnt.set_speed_b-angle_dev);
  6. // else if(mpu_angle<(angle_z+3))
  7. // moto_set_speed(gpt_cnt.set_speed_a-angle_dev,gpt_cnt.set_speed_b+angle_dev);
  8. // else
  9. // moto_set_speed(gpt_cnt.set_speed_a,gpt_cnt.set_speed_b);
  10. PID_Position_Calc(&ANGLE,Mpu_angle.angle_z+180.0f,angle_z/1.0f);//直线矫正
  11. gpt_cnt.set_speed_a=left_sp - ANGLE.output;
  12. gpt_cnt.set_speed_b=right_sp + ANGLE.output;
  13. }
  14. void car_follow(float now_distance,float next_distance)//小车位置-速度环 next_distance = 20
  15. {
  16. PID_Position_Calc(&distance,now_distance/1.0f,next_distance/1.0f);//位置环计算行驶距离误差
  17. PID_Incremental_Calc(&MOTOR_Spid[0], gpt_cnt.speed_a, distance.output);//速度环输出
  18. PID_Incremental_Calc(&MOTOR_Spid[1], gpt_cnt.speed_b, distance.output);
  19. moto_set_speed(MOTOR_Spid[0].output, MOTOR_Spid[1].output);//速度环输出项发送电机
  20. }
  21. void car_remove(float now_speed[2],float set_speed[2])//小车速度环
  22. {
  23. PID_Incremental_Calc(&MOTOR_Spid[0],now_speed[0], set_speed[0]);//速度环输出
  24. PID_Incremental_Calc(&MOTOR_Spid[1],now_speed[1], set_speed[1]);
  25. moto_set_speed(MOTOR_Spid[0].output, -MOTOR_Spid[1].output);//速度环输出项发送电机
  26. }

二、路径规划

1.编码器获取

  1. #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
  2. #pragma vector=PORT2_VECTOR
  3. __interrupt
  4. #elif defined(__GNUC__)
  5. __attribute__((interrupt(PORT2_VECTOR)))
  6. #endif
  7. void Port_2 (void)//编码器采用外部中断获取
  8. {
  9. if(GPIO_getInterruptStatus(GPIO_PORT_P2,GPIO_PIN4) == GPIO_PIN4)
  10. {
  11. if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN4) == GPIO_INPUT_PIN_HIGH)//上升沿
  12. {
  13. if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN0) == GPIO_INPUT_PIN_LOW)//正转
  14. {
  15. gpt_cnt.count_a --;
  16. }
  17. else//反转
  18. {
  19. gpt_cnt.count_a ++;
  20. }
  21. }
  22. GPIO_clearInterrupt(GPIO_PORT_P2,GPIO_PIN4);
  23. }
  24. }

2.小车任务三 

  1. void car_control_fort3(void) //任务三
  2. {
  3. run_distance = ((gpt_cnt.count_a+gpt_cnt.count_b)/2.0f)/Encoder_cnt*2.0f*3.14f*3.25f;//行驶距离 = 小车行驶总脉冲 / 1圈的脉冲值 * 2 * pi * 轮子半径
  4. switch(run_dis)
  5. {
  6. case 0:
  7. // navigation_execute(179.0f,set_sp,set_sp);//直线矫正
  8. sensor_checking(30,0,0);//开启循迹
  9. if(run_distance>=stright_dis+15.0f)//通过第一路口
  10. {
  11. gpt_cnt.set_speed_a = gpt_cnt.set_speed_b = 0;
  12. run_dis = 1;
  13. }
  14. break;
  15. case 1:
  16. car_follow(rec_distance-run_distance,200);//位置环控制小车
  17. sensor_checking(set_sp,min_sp,max_sp);//开启循迹
  18. if(run_distance >= cross_third)//判断位置到达第三路口
  19. {
  20. if(sensor_reading[1]&&sensor_reading[2]&&sensor_reading[3])//检测停止标志
  21. {
  22. DL20_AgreementDirectives(0x05,USCI_A1_BASE);//发送停车指令
  23. gpt_cnt.set_speed_a = gpt_cnt.set_speed_b = 0;
  24. if(systick_delay.count_1s != systick_delay.last_count_1s)//1ms
  25. {
  26. if(++delay_tim>=6)//1ms*6
  27. {
  28. DL20_AgreementDirectives(0x06,USCI_A1_BASE);//发送中途启动指令
  29. DL20_AgreementDirectives(0x06,USCI_A1_BASE);//发送中途启动指令
  30. run_dis = 2;
  31. }
  32. systick_delay.last_count_1s = systick_delay.count_1s;
  33. }
  34. }
  35. else
  36. {
  37. delay_tim = 0;
  38. }
  39. }
  40. break;
  41. case 2:
  42. sensor_checking(30,min_sp,max_sp);//开启循迹
  43. if(run_distance >= 580.0f)//一圈总距离584.8cm
  44. {
  45. if((sensor_reading[1]&&sensor_reading[2])||(sensor_reading[2]&&sensor_reading[3]))
  46. {
  47. gpt_cnt.set_speed_a = 0;
  48. gpt_cnt.set_speed_b = 0;
  49. DL20_AgreementDirectives(0x02,USCI_A1_BASE);//发送停车指令
  50. beep_on;
  51. run_flag = 0;
  52. }
  53. }
  54. break;
  55. }
  56. }

 

四、工程获取

代码及设计报告还在整理中,开学后会公布

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

闽ICP备14008679号