[uCOS/RTOS] 【RTOS】TARM端水机械臂控制卡

[复制链接]
1452|1
 楼主| tinnu 发表于 2020-7-6 02:30 | 显示全部楼层 |阅读模式
本帖最后由 tinnu 于 2020-7-13 20:01 编辑

一、概述
该参赛作品为针对液体搬运环境优化的机械臂下位机运动控制卡。针对日常生活中一个常见的场景——搬运液体(俗称“端水”),设计一项高效平稳的控制算法,配合自主开发的控制器驱动板卡,驱动自制的机械臂到达目标位置,使该算法达到高效平稳搬运液体的目的。


二、硬件方案
1-驱动方案
步进电机驱动:A4988+DRV8825
供电体系设计:12V DC输入,MP1584两路
角度反馈:两个MPU6500,通过IIC接口通讯

2-驱动板
驱动板为兼容RAMPS1.4设计:

3-控制板
控制板采用新塘的M451 64脚芯片作为主控,这款芯片位M4F架构,能充分发挥浮点运算能力与DSP运算能力,主频高达72MHz。
原理图、PCB工程:https://oshwhub.com/day_day/tarm_v1-4

三、软件方案
1-使能msh控制台
在rtconfig.h里面增加定义:
  1. #define FINSH_USING_MSH
如果定义 #define FINSH_USING_MSH_ONLY 还能直接进入msh模式,否则会进入C style,要键入msh()才能进入msh模式。
此外还能通过定义:

  1. #define FINSH_USING_HISTORY 0
  2. #define FINSH_HISTORY_LINES        1
使能历史指令

2-自定义三个个msh指令:
TARM_MOVXY
TARM_MOVR
TARM_CloopLoop
分别进行垂直面的驱动与回转面的驱动,置位作为标志位的全局变量,开始机械臂运动


  1. #ifdef FINSH_USING_MSH
  2. void TARM_MOVXY(int argc, char**argv)
  3. {
  4.         double x=0,y=0;
  5.         int speed=0;
  6.         char t_str[30];
  7.         if(argc <= 2 || argc >= 5)
  8.         {
  9.                 rt_kprintf("too little or too many arg!");
  10.                 return ;
  11.         }
  12.         x = atof(argv[1]);
  13.         y = atof(argv[2]);
  14.         if(argc==3)
  15.         {
  16.                 speed=100;
  17.         }
  18.         else if(argc==4)
  19.         {
  20.                 speed=atof(argv[3]);
  21.         }
  22. //        rt_kprintf("x-%f,y-%f,s-%f",x,y,speed);
  23.         g_TARM_RunRecord.ReadyRunLoc_x = x;
  24.         g_TARM_RunRecord.ReadyRunLoc_y = y;
  25.         g_TARM_RunRecord.ReadyRunLoc_speed = speed;
  26.         g_TARM_RunRecord.StartRun_pv =1;
  27.         sprintf(t_str,"_&x:%f;\t_&y:%f;\n_&speed:%d;\r\r\n",x,y,speed);
  28.         rt_kprintf(t_str);
  29. }
  30. MSH_CMD_EXPORT(TARM_MOVXY, mov with X Y speed : TARM_MOVXY 7.1 12.1 150.1);

  31. void TARM_MOVR(int argc, char**argv)
  32. {        
  33.         double r=0;
  34.         int speed=0;
  35.         char t_str[30];
  36.         if(argc <= 1 || argc >= 4)
  37.         {
  38.                 rt_kprintf("too little or too many arg!");
  39.                 return ;
  40.         }
  41.         r = atof(argv[1]);
  42.         if(argc==2)
  43.         {
  44.                 speed=100;
  45.         }
  46.         else if(argc==3)
  47.         {
  48.                 speed=atof(argv[2]);
  49.         }
  50.         g_TARM_RunRecord.ReadyRunLoc_r = r;
  51.         g_TARM_RunRecord.ReadyRunLoc_speedr = speed;
  52.         g_TARM_RunRecord.StartRun_r =1;
  53.         sprintf(t_str,"_&r:%f;\n_&speed:%d;\r\r\n",r,speed);
  54.         rt_kprintf(t_str);
  55. }
  56. MSH_CMD_EXPORT(TARM_MOVR, mov with X Y speed : TARM_MOVR 100 150.1);
  57. #endif
TARM_CloopLoop:

  1. #ifdef FINSH_USING_MSH
  2. void TARM_CloopLoop()
  3. {
  4.         rt_thread_resume(clossloop_update_thread);
  5. }
  6. MSH_CMD_EXPORT(TARM_CloopLoop, closeloop for once : TARM_CloopLoop);
  7. #endif



3-设计一个线程进行机械臂驱动
动驱动机械臂的循环操作函数:handle_pvMainLoop、handle_rMainLoop
创建一个线程,通过识别标志位判断是否驱动机械臂。
  1. static void TARM_DriverStepSteering(void *parameter)
  2. {
  3.     char t_strReport[30];
  4.     set_current_start();
  5.     while (1)
  6.     {
  7.         if (g_TARM_RunRecord.StartRun_pv == 0 && g_TARM_RunRecord.StartRun_r == 0)
  8.         {
  9.             //让出CPU
  10.             rt_thread_mdelay(500);
  11.             // rt_thread_suspend(rt_thread_self());
  12.             // rt_schedule();
  13.         }
  14.         else if (g_TARM_RunRecord.StartRun_pv != 0)
  15.         {
  16.             //驱动
  17.             handle_pvMainLoop(g_TARM_RunRecord.ReadyRunLoc_x,
  18.                               g_TARM_RunRecord.ReadyRunLoc_y,
  19.                               g_TARM_RunRecord.ReadyRunLoc_speed);
  20.             g_TARM_RunRecord.StartRun_pv = 0;
  21.             sprintf(t_strReport, "->pv arrive:\nx:%f\ty:%f\n",
  22.                     g_TARM_RunRecord.pv_current.x,
  23.                     g_TARM_RunRecord.pv_current.y);
  24.             rt_kprintf(t_strReport);<blockquote>rt_thread_mdelay(300);

4-设计一个线程进行反馈检测
  1. void clossloop_update()
  2. {
  3.         char t_strReport[100];
  4.         CloseLoop_Init();
  5.         while(1)
  6.         {
  7.                 rt_thread_suspend(rt_thread_self());
  8.         rt_schedule();
  9.                 CloseLoop_Gather();
  10.                 sprintf(t_strReport, "\n->closeloop result:\n\tpv arrive:\n\tx:%f\ty:%f\n",
  11.                                                 g_TARM_RunRecord.pv_current.x,
  12.                                                 g_TARM_RunRecord.pv_current.y);
  13.                 rt_kprintf(t_strReport);
  14.         }
  15. }
反馈检测一次会挂起,当被唤醒时更新一次数值。

四、程序源码

KEIL工程:


五、视频演示
机械臂驱动演示:https://v.youku.com/v_show/id_XNDczOTU2NDkyOA==.html
指令下发演示:

文档:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
pangkitty 发表于 2020-7-7 09:14 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

73

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部