1. 功能描述

R111样机是一款拥有12个自由度的串联仿生六足机器人。本文示例所实现的功能为:R111样机12自由度六足机器人原地舞蹈。

2. 结构说明

R111样机(R111b)由6个2自由度连杆仿生腿结构组成,2自由度连杆仿生腿两两对称组合,分别构成机器昆虫的三对足。三对足之间由零件结合固定,从而构成机器昆虫的本体,呈现出非常规整的模块化结构。

该2自由度串联结构由舵机1和舵机2驱动,其中舵机1实现腿部前后摆动,舵机2实现腿部的上下抬伸。其中抬伸通过一个平行四连杆ABCD作为传动结构以增加腿部的行程和增强腿部运动的稳定性。

3. 电子硬件

在这个示例中,我们采用了以下硬件,请大家参考:

主控板

Basra主控板(兼容Arduino Uno)

扩展板

SH-SR舵机扩展板

舵机 标准舵机
电池 7.4V锂电池

电路连接说明:

因为12自由度六足机器人结构上装有12个舵机,所以将采用 SH-SR舵机扩展板

舵机接线顺序:1、3; 4、 5; 6、 8;11、13;15、 21;24、26。

4. 功能实现

上位机:Controller 1.0

下位机编程环境:Arduino 1.8.19

4.1初始位置的设定

① 将Controller下位机程序servo.ino直接下载到主控板。这段代码供Controller上位机与主控板通信,并允许调试舵机。代码如下:

/*------------------------------------------------------------------------------------版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.Distributed under MIT license.See file LICENSE for detail or copy athttps://opensource.org/licenses/MITby 机器谱 2023-02-16 https://www.robotway.com/------------------------------*/#include <Tlc5940.h>#include <tlc_servos.h>int data_array[2] = {0,0};   //servo_pin: data_array[0], servo_value: data_array[1];String data = "";boolean dataComplete = false;void setup() {Serial.begin(9600);Tlc.init(0);tlc_initServos();delay(1000);}void loop() {while(Serial.available()){int B_flag, P_flag, T_flag;data = Serial.readStringUntil('\n');data.trim();for(int i=0;i<data.length();i++){//Serial.println(data[i]);switch(data[i]){case '#':B_flag = i;  break;case 'P':{String pin = "";P_flag = i;for(int i=B_flag+1;i<P_flag;i++){pin+=data[i];}data_array[0] = pin.toInt();}break;case 'T':{String angle = "";T_flag = i;for(int i=P_flag+1;i<T_flag;i++){angle += data[i];}data_array[1] = map(angle.toInt(), 500, 2500, 0, 180);}break;default: break;}     }/*Serial.println(B_flag);Serial.println(P_flag);Serial.println(T_flag);for(int i=0;i<2;i++){Serial.println(data_array[i]);}*/dataComplete = true;}if(dataComplete){tlc_setServo(data_array[0], data_array[1]);Tlc.update();dataComplete = false;}}

下载完成后,保持主控板和电脑的USB连接,并打开主控板电源,以便利用上位机进行调试。

② 双击打开Controller 1.0b.exe:

③ 点击联机,选择对应的端口号,波特率设置为9600,如下图所示:

控制块内容说明如下:

④ 此时上位机软件已经与下位机建立通信连接,我们拖动舵机引脚号对应的滑块即可对舵机进行角度调节。下图为软件中各个按钮说明:

软件各按钮说明

转换后的数据

⑤ 设置面板说明:点击左上角设置-设置面板,即可打开(如下图)。点击对应序号的复选框即可控制软件主界面中相应控制块的显示和隐藏,以及全部显示和全部隐藏等;点击重置按钮,可将各个控制块恢复初始位置;点击确定可关闭设置界面。

⑥ 控制块任意位置拖动:如下图,可拖动至需要的形状。

变化后的形状

注:每次重启会恢复初始位置

3.2 示例程序

调试好角度后,将角度参数复制到下面的12自由度六足机器人原地舞蹈的参考例程(robot_dance.ino)之中,并下载到主控板:

/*------------------------------------------------------------------------------------版权说明:Copyright 2023 Robottime(Beijing) Technology Co., Ltd. All Rights Reserved.Distributed under MIT license.See file LICENSE for detail or copy athttps://opensource.org/licenses/MITby 机器谱 2023-02-16 https://www.robotway.com/------------------------------*/#include <Arduino.h>#include <avr/pgmspace.h>#include "Config.h"#include <Tlc5940.h>#include <tlc_servos.h>int count_input = 0;boolean _b = false;/**************+++++++++++动作组数组,请将转换后的动作组数据粘贴到相应的动作组中+++++++***************************/const PROGMEM int actionInit[] = {1090, 1790, 1220, 980, 650, 1800, 1020, 1330, 520, 1155, 1260, 2020,1090, 1790, 1220, 980, 650, 1800, 1020, 1330, 520, 1155, 1260, 2020,};const PROGMEM int actionLeft[] = {};const PROGMEM int actionRight[] = {};const PROGMEM int actionBack[] = {};const PROGMEM int actionDance[] = {};const PROGMEM int actionDance[] = {1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,1090,1790,1220,980,650,1800,1020,1330,520,1155,1260,2020,1490,1590,1220,980,850,1400,1020,1330,1320,1155,1260,2020,1490,1590,1220,980,850,1400,1020,1330,1320,1155,1700,1700,1490,1590,1220,980,850,1400,1020,1330,1320,1155,1700,2020,1090,1790,1220,980,650,1800,1020,1330,520,1155,1260,2020,1490,1590,1220,980,850,1400,1020,1330,520,1155,1260,1220,1490,1590,1220,980,850,1400,1020,1330,800,700,1260,1220,1490,1590,1220,980,850,1400,1020,1330,520,700,1260,1220,1090,1790,1220,980,650,1800,1020,1330,520,1155,1260,2020,1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,1090,1190,1220,980,1370,1800,620,1730,1100,1155,1260,1430,1090,1190,1220,980,1370,1100,620,1730,1100,1155,1260,1430,1670,1190,1220,980,1370,1800,620,1730,1100,1155,1260,1430,1090,1190,1220,980,1370,1100,620,1730,1100,1155,1260,1430,1090,1190,1220,980,1370,1800,700,1570,1100,1155,1260,1430,1670,1190,1220,980,1370,1100,700,1570,1100,1155,1260,1430,1670,1190,1220,980,1370,1100,700,1570,520,520,1930,2020,1670,1190,1220,980,1370,1100,700,1570,800,520,1930,1700,1670,1190,1220,980,1370,1100,700,1570,520,520,1930,2020,1670,1190,1220,980,1370,1100,700,1570,800,520,1930,1700,1670,1190,1220,980,1370,1100,700,1570,1100,1155,1260,1430,1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,1670,1190,1220,980,900,1590,1020,1330,720,1155,1260,1430,1320,1540,1220,980,1370,1100,1020,1330,1100,1155,1260,1830,1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,1320,1410,1220,980,1370,1100,1020,1330,1100,1155,1260,1950,1300,1670,1220,980,1370,1100,1020,1330,1100,1155,1260,1600,1670,1190,1220,980,940,1540,1020,1330,920,1155,1260,1430,1670,1190,1220,980,1235,1480,1020,1330,580,1155,1260,1430,1670,1190,1220,980,940,1540,1020,1330,920,1155,1260,1430,1670,1190,990,1210,940,1540,1140,1100,920,1400,1060,1430,1300,1670,990,1210,1370,1100,1140,1100,1100,1400,1060,1600,1320,1540,990,1210,1370,1100,1140,1100,1100,1400,1060,1830,1670,1190,990,1210,1370,1100,1140,1100,1100,1400,1060,1430,1670,1190,990,1210,1370,1100,1140,1100,1100,1400,1060,1430,1670,1190,1280,920,1370,1100,920,1410,1100,1030,1410,1430,1670,1190,990,1210,1370,1100,1140,1100,1100,1400,1060,1430,1670,1190,1280,920,1370,1100,920,1410,1100,1030,1410,1430,1670,1190,1220,980,1370,1100,1020,1330,1100,1155,1260,1430,};/**************************+++++---------分割线--------++++++*******************************************************///动作组数组长度获取函数,增加动作组时需要按如下格式添加:actPwmNum[增加的动作组序号] = sizeof(增加的动作组名称) / sizeof(增加的动作组名称[0]);void act_length(){actPwmNum[0] = (sizeof(actionMove) / sizeof(actionMove[0]))/servo_num;actPwmNum[1] = (sizeof(actionLeft) / sizeof(actionLeft[0]))/servo_num;actPwmNum[2] = (sizeof(actionRight) / sizeof(actionRight[0]))/servo_num;actPwmNum[3] = (sizeof(actionBack) / sizeof(actionBack[0]))/servo_num;actPwmNum[4] = (sizeof(actionDance) / sizeof(actionDance[0]))/servo_num;actPwmNum[5] = (sizeof(actionInit) / sizeof(actionInit[0]))/servo_num;}//map映射函数long map_servo(long x, long in_min, long in_max, long out_min, long out_max){return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;}//PWM 转换为舵机角度的函数,增加动作组时需要修改void vlaue2angle(int p, int act){switch(act){case 0:   value_cur[p] = map_servo(pgm_read_word_near(actionMove + p + servo_num * count_input), 500, 2500, 0, 180);   break;case 1:   value_cur[p] = map_servo(pgm_read_word_near(actionLeft + p + servo_num * count_input), 500, 2500, 0, 180);   break;case 2:   value_cur[p] = map_servo(pgm_read_word_near(actionRight + p + servo_num * count_input), 500, 2500, 0, 180);   break;case 3:   value_cur[p] = map_servo(pgm_read_word_near(actionBack + p + servo_num * count_input), 500, 2500, 0, 180);   break;case 4:   value_cur[p] = map_servo(pgm_read_word_near(actionDance + p + servo_num * count_input), 500, 2500, 0, 180); break;case 5:   value_cur[p] = map_servo(pgm_read_word_near(actionInit + p + servo_num * count_input), 500, 2500, 0, 180); break;default: break;}}//舵机初始化函数,动作组第一行为舵机初始化值void servo_init(int act, int num){  if(!_b){for(int i=0;i<servo_num;i++){vlaue2angle(i, act);tlc_setServo(servo_pin[i], value_cur[i]);value_pre[i] = value_cur[i];}Tlc.update();//delay(1000);}num == 1 ? _b = true : _b = false;}//舵机移动函数,参数: act:动作组宏定义名称 ;num:动作组执行的次数,num > 0 ;void servo_move(int act, int num){  float value_delta[servo_num] = {};float in_value[servo_num] = {};servo_init(act, num);for(int i=0;i< num * actPwmNum[act];i++){count_input++;if(count_input == actPwmNum[act]){count_input = 0;continue;}for(int i=0;i<servo_num;i++){vlaue2angle(i, act);in_value[i] = value_pre[i];value_delta[i] = (value_cur[i] - value_pre[i]) / frequency;}for(int i=0;i<frequency;i++){for(int k=0;k<servo_num;k++){in_value[k] += value_delta[k];  value_pre[k] = in_value[k];}for(int j=0;j<servo_num;j++){       tlc_setServo(servo_pin[j], in_value[j]);delayMicroseconds(servo_speed);}Tlc.update();}delayMicroseconds(action_delay);}}/********************************************************-------分割线--------****************************************************///初始化函数void setup() {Serial.begin(9600);     //开启串口通信,波特率9600Tlc.init(0);tlc_initServos();act_length();delay(action_delay);}//主函数,跳舞void loop() {servo_move(action_dance, 2);delay(100);}

对于机器人来说,实现某一个自身结构的极限动作并不难,难度在于如何让动作变得有节奏-舞蹈。因为机器人无法达到人体的柔和度,所以为了让机器人跳舞更具有观赏性,建议大家选择节奏点清晰的音乐,尝试根据音乐节奏来设计舞蹈动作。

4. 扩展样机

改变足对之间的连接零件,就可以扩展出不同的样机,甚至还可以考虑在足对之间加入关节,使其具备更丰富的自由度。

5. 资料内容

①样机3D文件

②原地舞蹈-例程源代码

​③Controller1.0b资料包

④音乐素材.mp3

详细资料下载请参考 12自由度六足-原地舞蹈

12自由度六足机器人实现原地舞蹈功能相关推荐

  1. 12自由度六足机器人实现步态规划功能

    1. 运动功能描述 R111样机是一款拥有12个自由度的串联仿生六足机器人.本文示例实现12自由度六足机器人的行走功能,包括前进.后退.左转.右转. 2. 结构说明 R111样机由六个2自由度串联结构 ...

  2. 12自由度六足机器人实现蓝牙遥控

    1. 功能描述 R111样机是一款拥有12个自由度的串联仿生六足机器人.本文为这个六足机器人增加蓝牙遥控功能,可以通过安卓手机APP对机器人的动作实现遥控. 2. 电子硬件 在这个示例中,我们采用了以 ...

  3. 8及12自由度四足机器人VMC(虚拟模型)控制代码

    代码算法参考知乎:华北舵狗王--华北舵狗王带你一起做四足机器人3(Moco-8四足机器人导航算法简介) 参考论文:四足机器人对角小跑步态虚拟模型直觉控制方法研究 代码结构参考知乎 :xyYu 效果视频 ...

  4. 六足机器人的实现原理

    缘由: 在自然界和人类社会中存在一些人类无法到达的地方和可能危及人类生命的特殊场合.如行星表面.灾难发生矿井.防灾救援和反恐斗争等,对这些危险环境进行不断地探索和研究,寻求一条解决问题的可行途径成为科 ...

  5. STM32毕业设计——基于STM32+JAVA+Android的六足机器人控制系统设计与实现(毕业论文+程序源码)——六足机器人控制系统

    基于STM32+JAVA+Android的六足机器人控制系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于STM32+JAVA+Android的六足机器人控制系统设计与实现,文章末尾附有 ...

  6. 基于SIMULINK的六足机器人仿真

    六足机器人是机电高度集成的仿生系统,它的动态性能由其结构系统与控制系统一起决定.为了提高六足机器人整体的动态性能,对六足机器人进行集成优化设计.描述六足机器人系统的结构:根据六足机器人机构的几何特征, ...

  7. 6自由度双足机器人行走功能的实现

    1. 运动功能说明 6自由度双足机器人样机是一款拥有6自由度的串联型双足,相当于人形机器人的下半身.它可以实现抬腿.迈步.蹲下和起立.行走.翻跟头等等功能. 2. 结构说明 6自由度双足机器人样机的每 ...

  8. 【毕设】六足机器人的设计

    苍天下的蓝耀__[毕设]六足机器人的设计 序 这个项目是我本科毕业设计作品,可实现功能有常规控制(前后左右移动.左右自旋).保持自平衡.三档变速及自主避障功能,历时三个月在家独立完成.应各位的请求写一 ...

  9. V-REP 六足机器人教程

    在本教程中,我们将构建一个六足行走机器人.要确保在您开始看本教程之前已经阅读了 BubbleRob 教程以及导入和准备刚性体教程.与本教程( "hexapod.dxf" ) 有关, ...

最新文章

  1. 第二阶段第三次站立会议
  2. 想转行学python过来人提醒大家几点
  3. 【DIY】200521近期在做的项目小结,DIY进展汇报
  4. 架构之:软件架构漫谈
  5. ABAP面试题系列:写一组会出现死锁(Deadlock)的ABAP程序
  6. 分享百度文库提交成功的八大因素
  7. mysql报错Attempted to open a previously opened tablespace的解决办法
  8. 软件可用性测试mantis,可用性测试(软件/Web)
  9. strassen算法java_使用java写的矩阵乘法实例(Strassen算法)_Java_软件编程
  10. 代码描述10911 - Forming Quiz Teams
  11. 关于Jquery中 “$(document).ready(function(){ })”函数的使用
  12. ghost系统卡正在启动服务器,安装win7系统卡在正在启动windows界面的解决方法
  13. FLASH动画之制作动画
  14. 数据包络分析-BCC模型
  15. windows 查看ip命令
  16. 数据挖掘需要什么数学基础(一)
  17. QCC3040---multipoint function
  18. php1蛋白质带电情况,结合蛋白质(1)
  19. Eclipse使用JUnit4和Ant工具进行自动化测试的环境配置
  20. TradingView--前端(Vue)最专业的K线图表工具(只支持历史数据K线展示)

热门文章

  1. 高效管理你的碎片化知识——RSS打造完美信息流
  2. [BZOJ3637][LCT]Qtree6
  3. python考试简答题-python考核试题及答案
  4. 华北电力大学微型计算机,华北电力大学学报(自然科学版)
  5. Machine learning(ML)常用的几类学习器及Python实现
  6. Lode's Computer Graphics Tutorial Image Filtering
  7. FFMPEG4.1源码分析之 内存管理APIs av_malloc() av_mallocz()
  8. 云盘大规模关停真正原因:不赚钱
  9. android 打造万能keyStore
  10. No instances available for XXX