8自由度串联四足机器人实现前进功能

news2024/11/19 23:15:25

1. 功能说明

     本文示例将实现R253样机8自由度串联四足机器人前进的功能,该机构是由4个 2自由度串联仿生腿 组成。

2. 串联关节型机器人运动算法

      8自由度串联四足机器人的前进步态是将机器人四足分成两组腿(身体一侧的前足与另一侧的后足)分别进行摆动和支撑,即处于对角线上的两条腿的动作一样,均处于摆动相或均处于支撑相,如下图所示:

      当转向时对角线上的腿部摆动方向会跟前进步态不一样,如下图所示为一个左转的步态:

3. 电子硬件

     本实验中采用了以下硬件:

主控板

Basra主控板(兼容Arduino Uno)‍

扩展板

Bigfish2.1扩展板‍

电池7.4V锂电池

电路连接说明: D3、D4;D7、D 8;D11、D12;A2、A3为舵机引脚分别对应8自由度串联四足机器人在Bigfish扩展板上的连接位置

注意:两个舵机为一条腿,不要分开连接】

      这里需要注意下,因为该机器人结构上有8个舵机,而Bigfish扩展板上的舵机接口是6个,所以我们需要对Bigfish扩展板进行改装(通过跳线的方式将Bigfish扩展板上常规使用的传感器接口转为舵机接口)。

4. 功能实现

      编程环境:Arduino 1.8.19

      下面提供一个8自由度串联四足机器人步态前进的参考例程(_1_17.ino),将参考例程下载到主控板中,具体实验效果可参考官网演示视频。

/*------------------------------------------------------------------------------------

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

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

           https://opensource.org/licenses/MIT

           by 机器谱 2023-04-20 https://www.robotway.com/

  ------------------------------*/

/*------------------------------------------------------------------------------------

  实验功能:

    八自由度四足机器人运动

           

  实验接线:

                【--机器人头部(俯视图)--】

----------------------------------------------------



    左前腿[外侧腿----内侧腿]     右前腿[内侧腿----外侧腿]

            内侧    外侧                 内侧     外侧

             .--.      .--.                    .--.       .--.

             |   |---|   |                     |   |       |   |

    D3    |   |---|   |   D4        D7 |   |       |   | D8

             ---*   ---*                    *--*     *--*



    左后腿[外侧腿----内侧腿]     右后腿[内侧腿----外侧腿]

           内侧    外侧                  内侧     外侧

            .--.      .--.                    .--.       .--.

            |   |---|   |                     |   |      |   |

    A3   |   |---|   |   A2       D12 |   |      |   | D11

            ---*   ---*                    *--*    *--*

    ---------------------------------------------------

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

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

     https://opensource.org/licenses/MIT   by 机器谱 2023-04-20 https://www.robotway.com/

-------------------------------------------------------------------------------------*/

#include <Arduino.h>

#include <avr/pgmspace.h>

#include <Servo.h>

#include "Config.h"

#include "PROGMEM_DATA.h"


Servo myServo[8];


void act_length();      //动作数组长度计算

void ServoStart();      //舵机连接

void ServoStop();       //舵机断开

void ServoGo();         //舵机转动

void readProgmem();     //读取PWM值

void servo_init();      //舵机初始化

void servo_move();      //动作执行



void setup() {

  Serial.begin(9600);

  act_length();             

}


void loop() {

  servo_move(ACTION_INIT, 2);

  delay(1000);

  servo_move(ACTION_MOVE, 20);

  while(1){};

}


void act_length()

{

  actPwmNum[0] = (sizeof(actionInit) / sizeof(actionInit[0]))/SERVO_NUM;

  actPwmNum[1] = (sizeof(actionMove) / sizeof(actionMove[0]))/SERVO_NUM;

  actPwmNum[2] = (sizeof(actionBack) / sizeof(actionBack[0]))/SERVO_NUM;

  actPwmNum[3] = (sizeof(actionLeft) / sizeof(actionLeft[0]))/SERVO_NUM;

  actPwmNum[4] = (sizeof(actionRight) / sizeof(actionRight[0]))/SERVO_NUM;


  /*******************+++++++++此处可以添加PWM数组++++++++++++****************/

}


void ServoStart(int which){

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

  pinMode(servo_port[which], OUTPUT);

}


void ServoStop(int which){

  myServo[which].detach();

  digitalWrite(servo_port[which],LOW);

}


void ServoGo(int which , float where){

  ServoStart(which);

  myServo[which].writeMicroseconds(where);

}


void readProgmem(int p, int act){                                       

  switch(act)

  {

    case 0:   value_cur[p] = pgm_read_word_near(actionInit + p + (SERVO_NUM * count_input));   break;

    case 1:   value_cur[p] = pgm_read_word_near(actionMove + p + (SERVO_NUM * count_input));   break;

    case 2:   value_cur[p] = pgm_read_word_near(actionBack + p + (SERVO_NUM * count_input));   break;

    case 3:   value_cur[p] = pgm_read_word_near(actionLeft + p + (SERVO_NUM * count_input));   break;

    case 4:   value_cur[p] = pgm_read_word_near(actionRight + p + (SERVO_NUM * count_input));   break;

    default: break;

  }

}


void servo_init(int act, int num){                         

  if(!_b)

  {

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

    {

      readProgmem(i, act);

      ServoGo(i, value_cur[i]);

      value_pre[i] = value_cur[i];

    }

  }

  num == 1 ? _b = true : _b = false;

}


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++)

    {

      readProgmem(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++)

      {       

        ServoGo(j, in_value[j]);

      }

      delayMicroseconds(SERVO_SPEED);

    }


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

//    for(int i=0;i<SERVO_NUM;i++)

//    {

//      Serial.println(value_pre[i]);  

//    }

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

  }

}

      大家可根据转向的步态,参考上述例程,尝试自己编写下8自由度串联四足机器人转弯的实验程序。

5. 资料内容

①前进-例程源代码

②前进-样机3D文件

 资料内容详见:8自由度串联四足-前进

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/516761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

集群时间同步

集群时间同步 时间同步的方式&#xff1a;找一个机器&#xff0c;作为时间服务器&#xff0c;所有的机器与这台集群时间进行定时的同步&#xff0c;比如&#xff0c;每隔十分钟&#xff0c;同步一次时间。 1.配置时间同步具体实操&#xff1a; 1.1&#xff09;时间服务器配…

中国20强(上市)游戏公司2022年财报分析:营收结构优化,市场竞争进入白热化

易观&#xff1a;受全球经济增速下行的消极影响&#xff0c;2022年国内外游戏市场规模普遍下滑。但中国游戏公司凭借处于全球领先水平的研发、发行和运营的能力与经验&#xff0c;继续加大海外市场布局&#xff0c;推动高质量发展迈上新台阶。 风险提示&#xff1a;本文内容仅代…

lvm分区扩容

1.前言 此试验对root目录扩容20GB&#xff0c;使用lvm模式扩容&#xff0c;需要先声明&#xff0c;搭建centos主机的时候要把分区模式改成lvm模式&#xff0c;这样后期扩容的时候就比较好处理&#xff0c;如果使用了默认的part模式的话&#xff0c;扩容分区需要将数据先迁移备…

k8s架构了解

Kubernetes(k8s)是用于自动部署、扩展和管理“容器化应用程序”的开源系统 k8s由control plane以及cluster nodes构成 control plane control plane是维护所有k8s对象记录的系统&#xff0c;持续管理着对象状态&#xff0c;并且对集群的变化做出响应&#xff0c;并使状态匹…

2022年美国大学生数学建模竞赛B题水和水力发电分配解题全过程文档及程序

2022年美国大学生数学建模竞赛 B题 水和水力发电分配 原题再现&#xff1a; 背景:   几个世纪以来&#xff0c;人们在河流和溪流.上修建水坝来蓄水建造水库&#xff0c;以此作为管理供水的方式。这些水库储存各种用途的水(如农业、工业、住宅)&#xff0c;提供休闲和娱乐场…

git可视化管理工具SourceTree安装教程

一、背景 本文主要写给&#xff0c;不熟悉git命令或者不喜欢使用git命令的开发者使用&#xff0c;SourceTree可视化见面可以清晰操作git,管理项目方便&#xff0c;可追溯代码编写者及日期。轻松完成项目的dev、sit、线上环境代码管理与合并。无需使用git命令&#xff0c;彻底释…

北京筑龙参编的《国有企业采购操作规范(2023版)》发布

近日&#xff0c;中国物流与采购联合会发布《国有企业采购操作规范&#xff08;2023版&#xff09;》团体标准&#xff0c;北京筑龙作为起草单位之一参与编写。新版团体标准为国有企业编制采购管理制度、规范采购行为提供了参照和依据&#xff0c;有助于进一步提高国企采购的规…

【腾讯云 Finops Crane 集训营】深入了解 Crane 开源项目,集训营实验操作指南,体验过程总结

前言 最近有幸参与了腾讯云举办的Finops Crane的集训营。在这个过程中&#xff0c;老师认真指导&#xff0c;让我受益非浅&#xff0c;也让我真正理解了这一产品所带来的意义。 在听了老师们的介绍和讲解后&#xff0c;我马不停蹄地开始了自己摸索。首先是跟着视频和官方教程…

7.100ASK_V853-PRO开发板支持人形检测和人脸识别

1.前言 ​ V853 芯片内置一颗 NPU核&#xff0c;其处理性能为最大 1 TOPS 并有 128KB 内部高速缓存用于高速数据交换&#xff0c;支持 OpenCL、OpenVX、android NN 与 ONNX 的 API 调用&#xff0c;同时也支持导入大量常用的深度学习模型。本章提供一个例程&#xff0c;展示如…

银医一站式服务终端

01 发卡/充值/挂号业务 ●发卡就诊 ●预约挂号 ●当日挂号 ●自助充值 ●医保关联 ●预约取号 ●现金充值 ●核酸预约 02 打印业务 ●打印检验报告 ●打印检查报告 ●打印费用清单 ●打印病历报告 ●打印住院病历 ●打印检验条码 03 缴费结算业务 ●支付宝支付…

AttributeError: module ‘lib‘ has no attribute ‘X509_V_FLAG_CB_ISSUER_CHECK‘

terminal运行报错AttributeError: module lib has no attribute X509_V_FLAG_CB_ISSUER_CHECK 解决&#xff1a; pip install pyOpenSSL --upgrade

Log4j2远程命令执行(CVE-2021-44228)

漏洞原理 该漏洞是由于&#xff0c;在JNDI客户端的lookup()函数参数外部可控或Reference类构造方法的classFactoryLocation参数外部可控时&#xff0c;会使用户的JNDI客户端访问RMI注册表中绑定的恶意Reference类&#xff0c;从而加载远程服务器上的恶意class文件在客户端本地…

实现微信打开App功能

效果 要求 文档 开发标签文档 android接入指南 android实现 1.接入openSDK dependencies { api ‘com.tencent.mm.opensdk:wechat-sdk-android:6.8.0’ } 2.注册 需要在包名为&#xff08;applicationId&#xff09;wxapi的包下加入以上几个类。 类名功能AppRegister是一…

heic如何转换jpg格式?

heic如何转换jpg格式&#xff1f;HEIC是苹果推出的一种新型图片格式&#xff0c;它可以在保证高质量图像的同时减小图像文件的大小。虽然HEIC格式在iOS设备上使用广泛&#xff0c;但在其他操作系统或平台上&#xff0c;特别是Windows系统中&#xff0c;其兼容性和支持程度较差。…

蓝牙单连接和多连接知识

蓝牙单连接和多连接知识 生活中蓝牙连接多路蓝牙的情况越来越多&#xff0c;下面介绍下单连接和多连接的知识&#xff0c;供大家参考 一&#xff1a;蓝牙单连接 蓝牙单连接也称为Point-to-Point 点对点连接&#xff0c;是最常见的蓝牙连接场景,如手机<–>车载蓝牙。&…

〖Web全栈开发①〗—网络编程基础(上)

网络编程基础 网络编程网络编程概述TCP/IP协议IP地址什么是IPIP组成IP 地址使用过程查看IPIp地址分类&#xff1a;子网掩码 端口 socketSocket原理&#xff11;.什么是Socket2.创建一个tcp socket&#xff08;tcp套接字&#xff09; tcp 介绍 &#x1f3d8;️&#x1f3d8;️个…

安卓卡死,卡屏,死机,黑屏

(662条消息) 黑屏定屏那些事 - 系统机制&#xff0c;分析套路和实战&#xff08;系统篇&#xff09;_android黑屏问题分析_内核工匠的博客-CSDN博客

Java 是如何实现双亲委托加载机制的

Java 是一种面向对象的编程语言&#xff0c;它有一套独特的类加载机制。其中&#xff0c;双亲委托加载机制是 Java 类加载机制中的一个重要概念。本文将介绍 Java 的双亲委托加载机制是如何实现的&#xff0c;并解释其作用和优点。 Java 类加载机制 在 Java 中&#xff0c;类的…

树脂可以吸收水里的硝酸盐吗,饮用水矿泉水除硝酸盐,食品级树脂

使用常规的离子交换树脂处理含硫酸盐水中的硝酸盐是困难的。因为树脂几乎交换了水中的所有的硫酸盐后&#xff0c;才与水中的硝酸盐交换。也就是说&#xff0c;硫酸盐的存在会降低树脂对硝酸盐的去除能力。采用Tulsimer A-62MP除硝酸盐树脂优先交换硝酸盐&#xff0c;对硝酸盐的…

形态学运算与仿真:图像处理中形态学操作的简单解释

形态学是图像处理领域的一个分支&#xff0c;主要用于描述和处理图像中的形状和结构。形态学可以用于提取图像中的特征、消除噪声、改变图像的形状等。其中形态学的核心操作是形态学运算。 形态学运算是一种基于形状的图像处理技术&#xff0c;它是通过结构元素与图像进行特定运…