测试环境

大疆开发板 C型
STM32F407IGH6TR 芯片
冯哈伯 3863 直流电机 带减速箱(38:2)
RoboModule直流伺服电机驱动器 RMDS-303
RoboModule电机配置上位机
蓝牙模块
蓝牙调试助手APP
RT-Thread操作系统
面向对象模块接口设计
电机连接铝制腿部机构带动踢球

代码工程

stm32f407_DJIc.rar
工程基础:
LED频闪指示灯模块: https://www.yuque.com/wangxi_chn/qaxke0/mltilp
RoboModule电机群模块:https://www.yuque.com/wangxi_chn/qaxke0/ulrbrk
蓝牙驱动遥控模块:https://www.yuque.com/wangxi_chn/qaxke0/dmwgwv

工程组成

  • 没有进一步封装,直接调用各个模块的方法在主函数内组合作用
  • 报文协议等见RoboModule电机群模块:https://www.yuque.com/wangxi_chn/qaxke0/ulrbrk

    main

  • 初始化配置

    1. MODULE_LED dev_led_state =
    2. {
    3. .pin = GET_PIN(H, 10),
    4. .LED_TIME_CYCLE = 4000,
    5. .LED_TIME_OUTPUT = 200
    6. };
  • 运行频闪状态灯

    1. MODULE_BLUETOOTHHC06 dev_communicate =
    2. {
    3. .Property_UartDevName = "uart6",
    4. };
  • 蓝牙串口

    1. MODULE_ROBOMODULEGROUP dev_robomoduleGroup =
    2. {
    3. .Property_CanDevName = "can1",
    4. .Value_robomodule[ROBOMODULE_NUMID_1] =
    5. {
    6. .Property_Enable = 1,
    7. .Property_GroupID = ROBOMODULE_GROUPID_0,
    8. .Property_NumID = ROBOMODULE_NUMID_1,
    9. .Property_Mode = ROBOMODULE_MODE_LOCATION,
    10. },
    11. .Value_robomodule[ROBOMODULE_NUMID_2] =
    12. {
    13. .Property_Enable = 1,
    14. .Property_GroupID = ROBOMODULE_GROUPID_0,
    15. .Property_NumID = ROBOMODULE_NUMID_2,
    16. .Property_Mode = ROBOMODULE_MODE_LOCATION,
    17. },
    18. };
  • 用到的两个Robomodule

    • 设置ID分别为0组1号,0组2号
    • 均是位置模式

      1. Module_Led_Config(&dev_led_state);
      2. dev_led_state.Set(&dev_led_state,9);
      3. Module_RobomoduleGroup_Config(&dev_robomoduleGroup);
      4. Module_BlueToothHC06_Config(&dev_communicate);
  • 使能配置

    1. /* system running shine led thread */
    2. rt_thread_t led_thread = rt_thread_create("ledshine", led_shine_entry, RT_NULL,
    3. 512, RT_THREAD_PRIORITY_MAX - 3, 20);
    4. if (led_thread != RT_NULL){
    5. rt_thread_startup(led_thread);
    6. }
    7. /* motor control thread */
    8. rt_thread_t motor_thread = rt_thread_create("motor", motor_entry, RT_NULL,
    9. 1024, RT_THREAD_PRIORITY_MAX - 2, 20);
    10. if (motor_thread != RT_NULL){
    11. rt_thread_startup(motor_thread);
    12. }
    13. /* blue tooth updata thread */
    14. rt_thread_t bluetupdata_thread = rt_thread_create("bluetupdata", bluetupdata_entry, RT_NULL,
    15. 512, RT_THREAD_PRIORITY_MAX - 5, 20);
    16. if (bluetupdata_thread != RT_NULL){
    17. rt_thread_startup(bluetupdata_thread);
    18. }
    19. /* blue tooth updata thread */
    20. rt_thread_t bluetcontrol_thread = rt_thread_create("bluetcontrol", bluetcontrol_entry, RT_NULL,
    21. 512, RT_THREAD_PRIORITY_MAX - 5, 20);
    22. if (bluetcontrol_thread != RT_NULL){
    23. rt_thread_startup(bluetcontrol_thread);
    24. }
  • 创建线程

    • LED状态灯显示线程
    • 电机控制线程
    • 蓝牙接收数据更新线程
    • 蓝牙控制线程

      1. static void bluetcontrol_entry(void *parameter)
      2. {
      3. static rt_uint32_t time_1000m = 0;
      4. while(1)
      5. {
      6. rt_thread_mdelay(1);
      7. time_1000m++;
      8. switch(dev_communicate.Value_keyMask)
      9. {
      10. case (0x0001<<0):
      11. dev_robomoduleGroup.Value_robomodule[ROBOMODULE_NUMID_1].Value_motor_AimAngle= 27500; //360°
      12. dev_robomoduleGroup.Value_robomodule[ROBOMODULE_NUMID_2].Value_motor_AimAngle= -27500;
      13. dev_communicate.Value_keyMask = 0x0000;
      14. break;
      15. case (0x0001<<1):
      16. dev_robomoduleGroup.Value_robomodule[ROBOMODULE_NUMID_1].Value_motor_AimAngle=0;
      17. dev_robomoduleGroup.Value_robomodule[ROBOMODULE_NUMID_2].Value_motor_AimAngle=0;
      18. dev_communicate.Value_keyMask = 0x0000;
      19. break;
      20. case (0x0001<<2):
      21. break;
      22. case (0x0001<<3):
      23. break;
      24. case (0x0001<<4):
      25. break;
      26. case (0x0001<<5):
      27. break;
      28. case (0x0001<<6):
      29. break;
      30. case (0x0001<<7):
      31. break;
      32. case (0x0001<<8):
      33. break;
      34. case (0x0001<<9):
      35. break;
      36. case (0x0001<<10):
      37. break;
      38. case (0x0001<<11):
      39. break;
      40. }
      41. dev_communicate.Value_keyMask = 0x0000;
      42. if(time_1000m >= 1000)
      43. {
      44. time_1000m = 0;
      45. rt_int16_t temp = dev_robomoduleGroup.Value_robomodule[ROBOMODULE_NUMID_1].Value_motor_AimAngle*360/27500;
      46. dev_communicate.Method_Send(&dev_communicate,PARAM_SHOW_1,
      47. temp);
      48. }
      49. }
      50. }
  • 这里的蓝牙按键仅用到了的前两个

    注意

  • 在使用前一定要注意电机的方向,电机方向与很多因素有关

    • robomodule编码器接线
    • robomodule与电机电源接线
    • 上位机设置
    • 单片机发送的信息
  • 因此,在单片机发送信息控制电机前应当先通过上位机的反馈模式观察电机正向,尤其是左右两侧的电机方向是否一致,再给出控制信号
  • 两个电机控制方向不一致是十分危险的操作

    存在问题

  • 冯哈伯 3863的电机力量非常大,而电机和腿部连接的地方较为薄弱

  • 很容易造成电机转动,但腿部位置由于惯性不跟随的情况
  • 在足端撞击橄榄球的一瞬间尤为明显
  • 表现形式就是电机的位置信息与腿部位置信息不相符

    可能的解决途径

  • 仍旧采用位置控制,但是控制电机转过角度较多、

  • 这时其实足端位置已经不可知,我们只是利用了位置控制时的加速过程
  • 经过测试踢球表现也较好,但不可重复踢球,每次都需要断电归零位重新上电
  • 可以考虑通过操作手,手动调整足端归位,绝对位置控制变为增量控制
  • 但是这样就减少了部分自动流程,会影响时间和一致性
  • 最根本的解决办法还是电机和腿部的连接绝对固连,精准的位置控制才可实现