极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2689|回复: 0

如何让6自由度双足机器人翻跟头?

[复制链接]
发表于 2023-1-5 09:28:10 | 显示全部楼层 |阅读模式
本帖最后由 机器谱 于 2023-1-5 09:28 编辑

1. 功能描述
控制腿部舵机协调运动,使样机做出翻跟头的动作,本功能使用6自由度双足机器人样机。



2. 电子硬件
在这个示例中,采用了以下硬件,请大家参考:

主控板Basra(兼容Arduino Uno)
扩展板Bigfish2.1
电池7.4V锂电池

3. 运动控制
上位机:Controller 1.0
下位机编程环境:Arduino 1.8.19
(1)初始位置的设定:使用Controller上位机对机器人进行调试,调试目标为使机器人保持直立状态,并且保持右脚的支撑臂在前。
①将Controller下位机程序servo_bigfish.ino直接下载到主控板。这段代码供Controller上位机与主控板通信,并允许调试舵机。代码如下:

  1. /*------------------------------------------------------------------------------------

  2.   版权说明:Copyright 2022 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

  3.            Distributed under MIT license.See file LICENSE for detail or copy at

  4.            https://opensource.org/licenses/MIT

  5.            by 机器谱 2022-10-20 https://www.robotway.com/

  6.   ------------------------------

  7.   实验功能: 6自由度双足行走

  8.   -----------------------------------------------------

  9.   实验接线(从行走时朝前的方向看):

  10. 左侧髋:D4;右侧髋:D3;

  11. 左侧膝:D7;右侧膝:D5;

  12. 左侧踝:D11;右侧踝:D6

  13. ------------------------------------------------------------------------------------*/


  14. /*

  15. * Bigfish扩展板舵机口; 4, 7, 11, 3, 8, 12, 14, 15, 16, 17, 18, 19

  16. * 使用软件调节舵机时请拖拽对应序号的控制块

  17. */

  18. #include <Servo.h>


  19. #define ANGLE_VALUE_MIN 0

  20. #define ANGLE_VALUE_MAX 180

  21. #define PWM_VALUE_MIN 500

  22. #define PWM_VALUE_MAX 2500


  23. #define SERVO_NUM 12


  24. Servo myServo[SERVO_NUM];


  25. int data_array[2] = {0,0};   //servo_pin: data_array[0], servo_value: data_array[1];

  26. int servo_port[SERVO_NUM] = {4, 7, 11, 3, 8, 12, 14, 15, 16, 17, 18, 19};

  27. int servo_value[SERVO_NUM] = {};


  28. String data = "";


  29. boolean dataComplete = false;


  30. void setup() {

  31.   Serial.begin(9600);



  32. }


  33. void loop() {



  34.   while(Serial.available())

  35.   {

  36.     int B_flag, P_flag, T_flag;

  37.     data = Serial.readStringUntil('\n');

  38.     data.trim();

  39.     for(int i=0;i<data.length();i++)

  40.     {

  41.       //Serial.println(data[i]);

  42.       switch(data[i])

  43.       {

  44.         case '#':

  45.           B_flag = i;  

  46.         break;

  47.         case 'P':

  48.         {

  49.           String pin = "";

  50.           P_flag = i;

  51.           for(int i=B_flag+1;i<P_flag;i++)

  52.           {

  53.             pin+=data[i];

  54.           }

  55.           data_array[0] = pin.toInt();

  56.         }

  57.         break;

  58.         case 'T':

  59.         {

  60.           String angle = "";

  61.           T_flag = i;

  62.           for(int i=P_flag+1;i<T_flag;i++)

  63.           {

  64.             angle += data[i];

  65.           }

  66.           data_array[1] = angle.toInt();

  67.           servo_value[pin2index(data_array[0])] = data_array[1];

  68.         }

  69.         break;

  70.         default: break;

  71.       }     

  72.     }

  73.    

  74.     /*

  75.     Serial.println(B_flag);

  76.     Serial.println(P_flag);

  77.     Serial.println(T_flag);

  78.    

  79.     for(int i=0;i<2;i++)

  80.     {

  81.       Serial.println(data_array[i]);

  82.     }

  83.     */

  84.    

  85.     dataComplete = true;

  86.   }



  87.   if(dataComplete)

  88.   {

  89.     for(int i=0;i<SERVO_NUM;i++)

  90.     {

  91.       ServoGo(i, servo_value[i]);

  92.       /*********************************串口查看输出***********************************/

  93. //      Serial.print(servo_value[i]);

  94. //      Serial.print(" ");

  95.     }

  96. //    Serial.println();

  97.       /*********************************++++++++++++***********************************/


  98.     dataComplete = false;

  99.   }




  100. }


  101. void ServoStart(int which){

  102.   if(!myServo[which].attached() && (servo_value[which] != 0))myServo[which].attach(servo_port[which]);

  103.       else return;

  104.   pinMode(servo_port[which], OUTPUT);

  105. }


  106. void ServoStop(int which){

  107.   myServo[which].detach();

  108.   digitalWrite(servo_port[which],LOW);

  109. }


  110. void ServoGo(int which , int where){

  111.   ServoStart(which);

  112.   if(where >= ANGLE_VALUE_MIN && where <= ANGLE_VALUE_MAX)

  113.   {

  114.     myServo[which].write(where);

  115.   }

  116.   else if(where >= PWM_VALUE_MIN && where <= PWM_VALUE_MAX)

  117.   {

  118.     myServo[which].writeMicroseconds(where);

  119.   }

  120. }


  121. int pin2index(int _pin){

  122.   int index;

  123.   switch(_pin)

  124.   {

  125.     case 4: index = 0; break;

  126.     case 7: index = 1; break;

  127.     case 11: index = 2; break;

  128.     case 3: index = 3; break;

  129.     case 8: index = 4; break;

  130.     case 12: index = 5; break;

  131.     case 14: index = 6; break;

  132.     case 15: index = 7; break;

  133.     case 16: index = 8; break;

  134.     case 17: index = 9; break;

  135.     case 18: index = 10; break;

  136.     case 19: index = 11; break;

  137.   }

  138.   return index;

  139. }
复制代码

下载完成后,保持主控板和电脑的USB连接,以便利用上位机进行调试。
②双击打开Controller 1.0b.exe:





③界面左上角选择:设置-面板设置,弹出需要显示的调试块,可通过勾选隐藏不需要调试的舵机块:联机-选择主控板对应端口号以及波特率。


④拖动进度条,可以观察相应的舵机角度转动,直到样机姿态达到我们的预想目标。然后勾选左下角添加-转化,获得舵机调试的数组:



⑤该数组可直接复制到后面的行走程序中“各个舵机的初始位置”部分进行使用。

(2)编写并下载翻跟头程序的代码(R213b_Somersaults.ino)到主控板:
  1. /*------------------------------------------------------------------------------------

  2.   版权说明:Copyright 2022 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.

  3.            Distributed under MIT license.See file LICENSE for detail or copy at

  4.            https://opensource.org/licenses/MIT

  5.            by 机器谱 2022-10-20 https://www.robotway.com/

  6.   ------------------------------

  7.   实验功能: 6自由度双足翻跟头

  8.   -----------------------------------------------------

  9.   实验接线(从行走时朝前的方向看):

  10. 左侧髋:D4;右侧髋:D3;

  11. 左侧膝:D7;右侧膝:D8;

  12. 左侧踝:D11;右侧踝:D12.

  13. ------------------------------------------------------------------------------------*/

  14. #include <Servo.h>

  15. Servo myServo[6];

  16. int num = 20;

  17. int servo_port[6]={4,7,11,3,8,12};   //定义舵机;

  18. int servo_num = sizeof(servo_port)/sizeof(servo_port[0]);   //servo_pin length

  19. float value_init[6]={86,101,88,82,92,81}; //各个舵机的初始位置     


  20. #define servo_speed 110   //舵机时间;


  21. void setup() {

  22.   Serial.begin(9600);

  23.   reset();                //初始化舵机

  24.   delay(3000);

  25. }


  26. void loop() {

  27.    for(int i=0;i<3;i++)   //让机器人执行三次动作

  28.    {

  29.     delay(1000);

  30.     ketou();             //机器人头着地

  31.     delay(30);

  32.     zuofanzhuan();       //机器人4、7、11舵机所对应的腿翻转

  33.     delay(30);

  34.     youfanzhuan();       //机器人3、8、12舵机所对应的腿翻转

  35.     delay(30);

  36.     qili();              //机器人起立

  37.     delay(300);

  38.    }

  39.   servo_move(86,101,88,82,92,81);   //机器人翻三个跟头后一直保持直立状态

  40. delay(1/0);            //程序一直执行延时;

  41. }


  42. void qili()              //机器人起立

  43. {

  44.   servo_move(170,22,118,169,168,48);

  45.   servo_move(86,101,88,82,92,81);

  46. }


  47. void youfanzhuan()      //机器人3、8、12舵机所对应的腿翻转

  48. {

  49.   servo_move(7,176,56,169,168,48);

  50.   servo_move(170,22,118,169,168,48);     

  51. }


  52. void zuofanzhuan()      //机器人4、7、11舵机所对应的腿翻转

  53. {

  54.   servo_move(7,176,56,5,8,113);

  55.   servo_move(7,176,56,169,168,48);  

  56. }


  57. void ketou()             //机器人头着地

  58. {

  59.   servo_move(86,101,88,82,92,81);

  60.   servo_move(7,176,56,5,8,113);

  61. }


  62. void reset()             //初始化舵机

  63. {

  64.    for(int i=0; i<servo_num; i++)

  65.   {

  66.     ServoGo(i, value_init[i]);

  67.   }

  68. }



  69. void ServoGo(int which , int where)//给舵机写入相应角度

  70. {

  71.   if(where!=200)

  72.   {

  73.     if(where==201) ServoStop(which);

  74.     else

  75.     {

  76.       ServoStart(which);

  77.       myServo[which].write(where);

  78.     }

  79.   }

  80. }


  81. void ServoStart(int which)

  82. {

  83.   if(!myServo[which].attached())myServo[which].attach(servo_port[which]);

  84.   pinMode(servo_port[which], OUTPUT);

  85. }



  86. void ServoStop(int which)   //释放舵机

  87. {

  88.   myServo[which].detach();

  89.   digitalWrite(servo_port[which],LOW);

  90. }



  91. void servo_move(float value0, float value1, float value2, float value3, float value4, float value5)

  92. {



  93.   float value_arguments[] = {value0, value1, value2, value3, value4, value5};//定义新数组

  94.   float value_delta[servo_num];



  95.   for(int i=0;i<servo_num;i++)

  96.   {

  97.     value_delta[i] = (value_arguments[i] - value_init[i]) / num;//给要转动的舵机写入(转动的角度/num)度,并将该度数定义为新的数组

  98.   }



  99.   for(int i=0;i<num;i++)

  100.   {

  101.     for(int k=0;k<servo_num;k++)

  102.     {

  103.       value_init[k] = value_delta[k] == 0 ? value_arguments[k] : value_init[k] + value_delta[k];//将新写入的舵机角度与初始化舵机角度比较,如果

  104.                                                                                                 //与初始化角度不相同,则初始化角度+给要转动的舵机写入(转动的角度/num)度

  105.                                                                                                 //组成新的数组并作为初始舵机角度数组,否则,为初始舵机角度数组。

  106.     }

  107.    

  108.     for(int j=0;j<servo_num;j++)

  109.     {

  110.       ServoGo(j,value_init[j]);

  111.     }

  112.     delay(servo_speed);

  113.   }

  114. }
复制代码

4. 资料下载
资料内容6自由度双足-翻跟头-例程源代码

资料下载链接:https://www.robotway.com/h-col-160.html



本帖子中包含更多资源

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

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 18:43 , Processed in 0.044509 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表