小车接收线速度和角速度

小车通过USART5接收上位机发送的线速度和角速度

两轮差速运动

小车是一个刚体,所以轮子的每个位置角速度都是相同的, 而由于转弯半径不同,所以每个轮子的线速度会有所不同.
a3.jpg
速度推导左右轮转速
已知线速度为V,角速度为:w 那么左右轮速度应该等于多少呢?
a4.jpg
左右轮转速推导速度
已知左右轮的速度,我们推导当前小车前进的线速度和角速度
小车线速度公式:
image.png
小车角速度公式:
image.png
根据线速度和角速度计算左右轮子速度代码实现

  1. //属性
  2. //轮子直径
  3. #define WHEEL_DIAMETER 0.032
  4. //一圈的信号数
  5. #define WHEEL_TPR 1400
  6. //左右轮子距离
  7. #define WHEEL_DISTANCE 0.11
  8. #define PI 3.14159265158
  9. //根据线速度和角速度计算左右两个轮子的线速度
  10. void calc_left_right_vel(float vel,float ang,float*vl,float *vr){
  11. *vl = vel - ang*0.5*WHEEL_DISTANCE;
  12. *vr = vel + ang*0.5*WHEEL_DISTANCE;
  13. }

pid调节左右轮子移动速度

  1. //接收上位机的线速度和角速度
  2. float vel = 0.1;
  3. float ang = -0.3;
  4. //左右轮子目标速度
  5. float vl = 0;
  6. float vr = 0;
  7. float hz = 20;
  8. //左右轮子当前速度
  9. float cur_vl = 0;
  10. float cur_vr = 0;
  11. float kp = 200;
  12. float ki = 0;
  13. float kd = 150;
  14. //左轮误差
  15. float pre_error_left = 0;
  16. float pre_error_right = 0;
  17. float total_error_left = 0;
  18. float total_error_right = 0;
  19. //左右轮子的pwm
  20. float pwm_left = 0;
  21. float pwm_right = 0;
  22. //左侧轮子pid控制
  23. int pid_left(float tar,float cur){
  24. float cur_error = tar-cur;
  25. pwm_left+=kp*cur_error;
  26. total_error_left+=cur_error;
  27. pwm_left+=ki*total_error_left;
  28. pwm_left+=kd*(cur_error-pre_error_left);
  29. pre_error_left=cur_error;
  30. return (int)pwm_left;
  31. }
  32. //右侧轮子pid控制
  33. int pid_right(float tar,float cur){
  34. float cur_error = tar-cur;
  35. pwm_right+=kp*cur_error;
  36. total_error_right+=cur_error;
  37. pwm_right+=ki*total_error_right;
  38. pwm_right+=kd*(cur_error-pre_error_right);
  39. pre_error_right=cur_error;
  40. return (int)pwm_right;
  41. }

控制主逻辑

  1. while(1){
  2. //根据线速度和角速度计算
  3. calc_left_right_vel(vel,ang,&vl,&vr);
  4. //当前速度
  5. cur_vl = (bsp_encoder_get_left()*hz*1.0)/WHEEL_TPR*WHEEL_DIAMETER*PI;
  6. cur_vr = (bsp_encoder_get_right()*hz*1.0)/WHEEL_TPR*WHEEL_DIAMETER*PI;
  7. printf("vl:%f,vr:%f,cur_vl:%f,cur_vr:%f\n",vl,vr, cur_vl,cur_vr);
  8. //通过pid计算两侧的轮子pwm
  9. //bsp_motor_set(pid_left(vl,cur_vl),pid_right(vr,cur_vr));
  10. delay_1ms(1000/hz);
  11. }