【开源获奖案例】四轴机械臂控制系统

描述

——来自迪文开发者论坛
本期为大家推送迪文开发者论坛获奖开源案例——四轴机械臂控制系统。工程师采用T5L智能屏,基于DGUS软件“旋转指示”控件实现机械臂的实时位置显示,并通过串口控制机械臂的运动过程。不同以往只展示机械臂的角度数值,该方案可以实现在屏幕上实时显示机械臂的旋转状态。除此之外,工程师还增加了机械臂自动运动功能。


 

  UI素材展示    UI素材可根据实际的应用进行多样化的设计,工程师设计了一套富有科技感的界面。

冗余机械臂

冗余机械臂

 

  UI开发示例   冗余机械臂   C51代码设计     

(1)获取机械臂当前控制的角度:

//获取机械臂状态
void get_arm_config_status(){    u8 i = 0;    for(i = 0;i < 4;i++)    {        arm_angle_value[i] = Read_Dgus(0x1100 + i * 2);        //Write_Dgus(0x1110 + i * 2, Va[i]);    }}

(2)机械臂的运动过程设计:使机械臂根据设置的角度,缓慢移动到指定位置。
 

//设置机械臂角度
void set_arm_angle(){    int i = 0;    for(i = 0;i < 4;i++)  

  {        if(arm_angle_value[i] != arm_angle_value_last[i])     

   {            if(arm_angle_value[i] < arm_angle_value_last[i])          

  {                arm_angle_value_last[i]--;            }          

  else     

       {                arm_angle_value_last[i]++;            }   

         Write_Dgus(0x1110 + i * 2, arm_angle_value_last[i]);            if(i == 1) //第二轴运动 

           {                u16 armiii_pos_x = 0;                u16 armiii_pos_y = 0;                u16 armiv_pos_x = 0;                u16 armiv_pos_y = 0;                armiii_pos_x = sin((float)(225 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 80 + armii_start_pos[0];                armiii_pos_y = cos((float)(225 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 80 + armii_start_pos[1];                armiv_pos_x = sin((float)(180 - arm_angle_value_last[i+1]) * TRIGONOMETRIC) * 83 + armiii_pos_x;                armiv_pos_y = cos((float)(180 - arm_angle_value_last[i+1]) * TRIGONOMETRIC) * 83 + armiii_pos_y;                armiii_current_pos[0] = armiii_pos_x;                armiii_current_pos[1] = armiii_pos_y;                OneSendData4(armiii_pos_x/256);                OneSendData4(armiii_pos_x%256);                OneSendData4(armiii_pos_y/256);                OneSendData4(armiii_pos_y%256);                Write_Dgus(0x2100 + 4, armiii_pos_x); //第三轴的位置                Write_Dgus(0x2100 + 5, armiii_pos_y);                Write_Dgus(0x2200 + 4, armiv_pos_x); //第三轴的位置                Write_Dgus(0x2200 + 5, armiv_pos_y);            }  

 

          else if(i == 2)         

  {                u16 armiv_pos_x = sin((float)(180 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 83 + armiii_current_pos[0];                u16 armiv_pos_y = cos((float)(180 - arm_angle_value_last[i]) * TRIGONOMETRIC) * 83 + armiii_current_pos[1];                Write_Dgus(0x2200 + 4, armiv_pos_x); //第三轴的位置                Write_Dgus(0x2200 + 5, armiv_pos_y);        

    }            break;     

   }    }}(3)按键设计:开发者设计了复位、添加、删除、开始、停止按键功能//获取按键状态
void get_key_status(u16 addr){    u16 Va=Read_Dgus(addr);    //u16 V1=Read_Dgus(0x0f01);    if(Va != 0x0000)   

 {        if(Va == 0x0001) //复位    

    {            Write_Dgus(0x1100 + 0, 0);            Write_Dgus(0x1100 + 2, 0);            Write_Dgus(0x1100 + 4, 0);            Write_Dgus(0x1100 + 6, 90);        }   

     else if(Va == 0x0002) //添加      

  {            if(arm_auto_cnt < 5)            {                u8 i = 0;                u8 send_str[30] = {0};                for(i = 0;i < 4;i++)                {                    arm_auto_list[arm_auto_cnt][i] = arm_angle_value[i];                }                sprintf(send_str, "I:%d II:%d III:%d IV:%d", arm_auto_list[arm_auto_cnt][0], arm_auto_list[arm_auto_cnt][1], arm_auto_list[arm_auto_cnt][2], arm_auto_list[arm_auto_cnt][3]);                write_dgus_vp(0x1500 + 0x20 * arm_auto_cnt, send_str, 16);                arm_auto_cnt++;            }        } 

       else if(Va == 0x0003) //开始        {            auto_start_flag = 1;            auto_start_cnt = 0;        }    

    else if(Va == 0x0004) //停止        {            auto_start_flag = 0;            Write_Dgus(0x1100 + 0, arm_angle_value_last[0]);            Write_Dgus(0x1100 + 2, arm_angle_value_last[1]);            Write_Dgus(0x1100 + 4, arm_angle_value_last[2]);            Write_Dgus(0x1100 + 6, arm_angle_value_last[3]);        }    

    else if(Va >= 0x0010 && Va <= 0x0014) //删除内容    

    {            u16 delete_select = Va - 0x0010;            if(arm_auto_cnt > delete_select) //有删除的内容         

  {                u8 i = 0;                u8 send_str[30] = {0};                for(i = delete_select;i < arm_auto_cnt - 1;i++)                {                    memcpy(arm_auto_list[i], arm_auto_list[i + 1], 8);                }        

        memset(arm_auto_list[i], 0, 8);                for(i = delete_select;i < arm_auto_cnt - 1;i++)              

  {                    sprintf(send_str, "I:%d II:%d III:%d IV:%d\0", arm_auto_list[i][0], arm_auto_list[i][1], arm_auto_list[i][2], arm_auto_list[i][3]);                    write_dgus_vp(0x1500 + 0x20 * i, send_str, 16);                }                memset(send_str, 0, 30);                write_dgus_vp(0x1500 + 0x20 * i, send_str, 16);                arm_auto_cnt--;            }        }        Write_Dgus(addr, 0);    }}(4)机械臂自动运动功能//自动运动
void auto_run(){    if(auto_start_flag == 1 && arm_auto_cnt >= 2) //动作必须两个及以上    {        if(memcmp(arm_angle_value, arm_auto_list[auto_start_cnt], 8) != 0) //不等于    

    {            Write_Dgus(0x1100 + 0, arm_auto_list[auto_start_cnt][0]);            Write_Dgus(0x1100 + 2, arm_auto_list[auto_start_cnt][1]);            Write_Dgus(0x1100 + 4, arm_auto_list[auto_start_cnt][2]);            Write_Dgus(0x1100 + 6, arm_auto_list[auto_start_cnt][3]);        }    

    else if(memcmp(arm_angle_value_last, arm_auto_list[auto_start_cnt], 8) == 0) //当前运动等于目标     

   {            auto_start_cnt++;            if(auto_start_cnt >= arm_auto_cnt)         

   {                auto_start_cnt = 0;            }        }    }}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分