12自由度六足机器人实现蓝牙遥控
1. 功能描述
R111样机是一款拥有12个自由度的串联仿生六足机器人。本文为这个六足机器人增加蓝牙遥控功能,可以通过安卓手机APP对机器人的动作实现遥控。
2. 电子硬件
在这个示例中,我们采用了以下硬件,请大家参考:
主控板 |
Basra主控板(兼容Arduino Uno) |
扩展板 |
SH-SR舵机扩展板 |
舵机 | 标准舵机 |
电池 | 7.4V锂电池 |
通信 |
蓝牙串口模块 |
电路连接说明:
12自由度六足机器人结构上装有12个舵机,所以将采用 SH-SR舵机扩展板 。
舵机接线顺序:1、3; 4、 5; 6、 8;11、13;15、 21;24、26。
蓝牙串口模块可以通过杜邦线与扩展板进行连接,具体可以参考 如何使用探索者通信模块 一文中蓝牙串口模块部分。
3. 功能实现
下面的例程可以实现通过安卓手机APP按钮实现机器人前进、后退、左转、右转、跳舞等动作。安卓APP的设置也可以参考 如何使用探索者通信模块一文中蓝牙串口模块部分。
你也可以设计自己想要的动作,利用Controller 1.0b软件获取想要的动作参数,拷贝到下面的例程里。
将参考例程(R111_bluetooth.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,// 1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,// 1090, 1790, 1220, 980, 650, 1800, 1020, 1330, 520, 1155, 1260, 2020};const PROGMEM int actionMove[] = {1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,1660, 1790, 1320, 1080, 1280, 1800, 920, 1230, 1090, 1255, 1360, 2020,1660, 1230, 1320, 1080, 1280, 1190, 920, 1230, 1090, 1255, 1360, 1540,1090, 1300, 1120, 880, 650, 900, 1120, 1430, 520, 1055, 1160, 1300,1660, 1300, 1120, 880, 1280, 900, 1120, 1430, 1090, 1055, 1160, 1300,};const PROGMEM int actionLeft[] = {1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,1080,1160,1420,780,650,1100,1220,1130,520,955,1460,1430,1700,1160,1420,780,1440,1100,1220,1130,1100,955,1460,1430,1700,1700,1020,1180,1440,1800,820,1530,1100,1355,1060,2020,1700,1160,1020,1180,1440,1100,820,1530,1100,1355,1060,1430,};const PROGMEM int actionRight[] = {1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,1700,1700,1420,780,1440,1800,1220,1130,1100,955,1460,2020,1700,1160,1420,780,1440,1100,1220,1130,1100,955,1460,1430,1090,1160,1020,1180,650,1100,820,1530,520,1355,1060,1430,1700,1160,1020,1180,1440,1100,820,1530,1100,1355,1060,1430,};const PROGMEM int actionBack[] = {1660, 1230, 1220, 980, 1280, 1190, 1020, 1330, 1090, 1155, 1260, 1540,1700,1680,1020,780,1440,1800,1220,1530,1100,955,1060,2020,1700,1060,1020,780,1440,1100,1220,1530,1100,955,1060,1430,1100,1060,1220,1180,650,1100,1020,1130,520,1355,1260,1430,1700,1060,1220,1180,1440,1100,1020,1130,1110,1355,1260,1430,};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;// for(int i=0;i<act_num;i++)// {// Serial.println(actPwmNum[i]); // }//---+++---在此处添加------+++-------}//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++){//Serial.println(i);//Serial.println(count_input);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;/**************************************************串口查看输出**************************************************/// Serial.print(value_pre[i]);// Serial.print(" ");// Serial.print(value_cur[i]);// Serial.print(" ");// Serial.print(value_delta[i]);// Serial.println();/**************************************************串口查看输出**************************************************/}// Serial.println();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];/**************************************************串口查看输出**************************************************/// Serial.print(in_value[k]);// Serial.print(" ");/**************************************************串口查看输出**************************************************/}// Serial.println();for(int j=0;j<servo_num;j++){ tlc_setServo(servo_pin[j], in_value[j]);delayMicroseconds(servo_speed);}Tlc.update();}delayMicroseconds(action_delay);/**************************************************串口查看输出**************************************************/// for(int i=0;i<servo_num;i++)// {// Serial.println(value_pre[i]); // }/**************************************************串口查看输出**************************************************/}}/********************************************************-------分割线--------****************************************************///初始化函数void setup() {Serial.begin(9600); //开启串口通信,波特率9600Tlc.init(0);tlc_initServos();act_length();delay(action_delay);}//主函数,三种执行动作的方式void loop() {/*********************************************+++++++++++++ 1、串口控制+++++++++**************************************************/// while(Serial.available())// {// int data;// data = Serial.parseInt();//// switch(data)// {// case 1: servo_move(action_move, 2); break;// case 2: servo_move(action_back, 2); break;// case 3: servo_move(action_left, 1); break;// case 4: servo_move(action_right, 1); break;// case 5: servo_move(action_dance, 1); break;// case 6: servo_move(action_init, 1); break;// case 7:// {// servo_move(action_move, 4);// delay(actChangeDelay);// servo_move(action_back, 4);// delay(actChangeDelay);// servo_move(action_left, 4);// delay(actChangeDelay);// servo_move(action_right, 4);// delay(actChangeDelay);// servo_move(action_dance, 2);// }// break;// default: break; // }// }/*****************************+++++++++++++ 2、指定每个动作执行的次数,以 while 循环结束+++++++++********************************/servo_move(action_move, 6);delay(actChangeDelay);servo_move(action_back, 6);delay(actChangeDelay);servo_move(action_left, 4);delay(actChangeDelay);servo_move(action_right, 4);delay(actChangeDelay);servo_move(action_dance, 2);delay(1000);// while(1){ };/****************************+++++++++++ 3、重复执行一个动作,次数设置为 1 ,取消 while 循环++++++++******************************/// servo_move(action_dance, 1);// while(1){};}
4. 资料内容
① 蓝牙遥控-例程源代码
② Controller1.0b资料包
资料内容详见 12自由度六足-蓝牙遥控
12自由度六足机器人实现蓝牙遥控相关推荐
- 12自由度六足机器人实现步态规划功能
1. 运动功能描述 R111样机是一款拥有12个自由度的串联仿生六足机器人.本文示例实现12自由度六足机器人的行走功能,包括前进.后退.左转.右转. 2. 结构说明 R111样机由六个2自由度串联结构 ...
- 12自由度六足机器人实现原地舞蹈功能
1. 功能描述 R111样机是一款拥有12个自由度的串联仿生六足机器人.本文示例所实现的功能为:R111样机12自由度六足机器人原地舞蹈. 2. 结构说明 R111样机(R111b)由6个2自由度连杆 ...
- 8及12自由度四足机器人VMC(虚拟模型)控制代码
代码算法参考知乎:华北舵狗王--华北舵狗王带你一起做四足机器人3(Moco-8四足机器人导航算法简介) 参考论文:四足机器人对角小跑步态虚拟模型直觉控制方法研究 代码结构参考知乎 :xyYu 效果视频 ...
- 六足机器人的实现原理
缘由: 在自然界和人类社会中存在一些人类无法到达的地方和可能危及人类生命的特殊场合.如行星表面.灾难发生矿井.防灾救援和反恐斗争等,对这些危险环境进行不断地探索和研究,寻求一条解决问题的可行途径成为科 ...
- STM32毕业设计——基于STM32+JAVA+Android的六足机器人控制系统设计与实现(毕业论文+程序源码)——六足机器人控制系统
基于STM32+JAVA+Android的六足机器人控制系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于STM32+JAVA+Android的六足机器人控制系统设计与实现,文章末尾附有 ...
- 白泽六足机器人_arduino_v1——3D打印开源六足机器人程序
导航在这里:白泽六足机器人_ros_v1 趁着五一帮忙做了一个六足机器人的程序,可以实现前后左右和超声波避障. 图片如下,可以避障,感兴趣的可以去抖音看具体运行视频. 1.打印结构并组装 这个结构在网 ...
- 基于SIMULINK的六足机器人仿真
六足机器人是机电高度集成的仿生系统,它的动态性能由其结构系统与控制系统一起决定.为了提高六足机器人整体的动态性能,对六足机器人进行集成优化设计.描述六足机器人系统的结构:根据六足机器人机构的几何特征, ...
- 6自由度双足机器人行走功能的实现
1. 运动功能说明 6自由度双足机器人样机是一款拥有6自由度的串联型双足,相当于人形机器人的下半身.它可以实现抬腿.迈步.蹲下和起立.行走.翻跟头等等功能. 2. 结构说明 6自由度双足机器人样机的每 ...
- 【毕设】六足机器人的设计
苍天下的蓝耀__[毕设]六足机器人的设计 序 这个项目是我本科毕业设计作品,可实现功能有常规控制(前后左右移动.左右自旋).保持自平衡.三档变速及自主避障功能,历时三个月在家独立完成.应各位的请求写一 ...
最新文章
- Android 中一些常用类的常用方法(Math、Random、Color、Paint、Canvas、Bitmap、BitmapFactory)...
- Too many open files问题解决
- 【转】PBOC3.0和PBOC2.0标准规范异同分析
- Java集合工具类的一些坑,Arrays.asList()、Collection.toArray()...
- distri.lua的web运维工具
- ROS中关于yaml文件参数的读取,和nh.param函数
- 内存的物理结构和工作原理
- API接口电商平台商品详情,网络爬虫数据(步骤示例,参数返回值说明)
- [技巧]深入了解强大的 ES6 「 ... 」 运算符
- 青龙面板扩展定时任务——九章头条
- 论文笔记 ACL 2017|Exploiting Argument Information to Improve Event Detection via Supervised Attention
- EMC设计经典15问
- 常见遥感卫星基本参数大全
- [白话解析] 通俗解析集成学习之GBDT
- html画流程图插件,基于SVG的流程图插件Flowchart.js
- 感悟爱情的空间说说:总有一个人,一直住在心底,却消失在生活里。
- python求一年的第几天_Python编程判断这天是这一年第几天的方法示例
- 艾美捷RPMI-1640培养基含L-谷氨酰胺的功能和研究
- 【转摘】在Word中使用SmartArt绘制组织结构图
- Mybatis03-封装MybatisUtil实体类
热门文章
- Ubuntu安装wps2019
- 【面向对象课程项目:纸牌】Java实例学习(一):优秀源码的分析
- inaflash什么意思中文_adobe flash是什么意思
- MySQL8.0 驱动jar包
- HTML开发实例-简单相亲网站开发(主体为table)
- 淘宝搬家助手(移动版)使用教程
- 关于获取来电显示的idea
- mssql 计划怎每隔n秒_自闭症孩子各方面能力训练计划纲要
- 422器件与lvds接收器的区别_一文读懂RS232与RS422及RS485三者之间的特性与区别
- 连接远程数据库,并通过SQL来获取数据;