“Hopf Oscillator-Based Gait Transition for A Quadruped Robot“代码复现

news2025/1/17 17:53:05

paper链接:https://ieeexplore.ieee.org/abstract/document/7090642/

import math
import numpy as np
import matplotlib.pyplot as plt

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号'-'显示为方块的问题

class CPG(object):
    def __init__(self, gait=0):

        self.gait_num = 3
        self.gait_names = ["Walk","Trot", "Pace", "Bound"]
        self.labels = ['FL', 'FR', 'HL', 'HR']

        # CPG构建基本参数
        self._alpha = 100
        self.leg_num = 4
        self.gait = gait
        self.mu_ = -1
        self._a = 50
        self.u1 = 0
        self.u2 = 0

        # 负载系数对相关参数影响
        self.BEAT_ = [0.75, 0.5, 0.5, 0.5]
        self.period_ = [0.6, 0.5, 0.5, 0.4]
        self._beta = self.BEAT_[0]
        self._t = self.period_[0]

        # 时间
        self.t_step = 0.001

        self.point_x = np.zeros(self.leg_num)
        self.point_y = np.zeros(self.leg_num)

        self.PHASE = [
            [0 * 2 * np.pi, 0.5 * 2 * np.pi, 0.25 * 2 * np.pi, 0.75 * 2 * np.pi],
            [0 * 2 * np.pi, 0.5 * 2 * np.pi, 0.5 * 2 * np.pi, 0 * 2 * np.pi],
            [0 * 2 * np.pi, 0.5 * 2 * np.pi, 0 * 2 * np.pi, 0.5 * 2 * np.pi],
            [0 * 2 * np.pi, 0 * 2 * np.pi, 0.5 * 2 * np.pi, 0.5 * 2 * np.pi],
        ]
        
        # 相对相位矩阵
        self.R_cell = np.zeros(shape=(self.leg_num, self.leg_num, 2, 2))

        self.Phi = None

        # 初始值,非0即可
        self.leg_x = None
        self.leg_y = None

        self.reset()
        
        # 计数,什么时候完成相位同步
        self.count_ = 0
        # 计数,什么时候结束步态转换
        self.t_count_ = 0

        self.init_phase()

    def init_phase(self):
        for _ in range(700):
            self.step()
    
    def reset(self):
        self._beta = self.BEAT_[self.gait]
        self._t = self.period_[self.gait]
        self.Phi = self.PHASE[self.gait]

        self.leg_x = np.ones(self.leg_num) * 0.0001
        self.leg_y = np.ones(self.leg_num) * 0.0001

        self.update_rotation_matrix()

    def next_gait(self):
        self.gait = (self.gait + 1) % self.gait_num
        self.reset()
        
    def update_rotation_matrix(self):        
        for i in np.arange(0, self.leg_num):
            for j in np.arange(0, self.leg_num):
                self.R_cell[j, i] = np.array([
                    [np.cos(self.Phi[i] - self.Phi[j]), - np.sin(self.Phi[i] - self.Phi[j])],
                    [np.sin(self.Phi[i] - self.Phi[j]), np.cos(self.Phi[i] - self.Phi[j])]
                ])
    
    def transit_gait(self, tau=0):
        self.t_count_ = self.t_count_ + 1
        # 步态在一个周期内完成转换
        if tau == 0:
            # walk to trot
            # beta/φ2从0.75变换到0.5
            # walk步态周期为0.6,假设在1s内完成转换,共200步,每步变换1/800=0.00125
            transit_step = 0.00125
            self.Phi[0] = 0
            # self.Phi[1] = 0.5
            phi2_ = 0.75 - transit_step * self.t_count_
            self.Phi[2] = phi2_ * 2 * np.pi
            self.Phi[3] = (phi2_ - 0.5) * 2 * np.pi
            # 更新占空比参数和周期参数
            self._beta = phi2_            
        else:
            # trot to gallop
            # φ1从0.5到0,0.5/200=1/400=0.0025
            transit_step = 0.0025
            phi1_ = 0.5 - transit_step * self.t_count_
            self.Phi[1] = phi1_ * 2 * np.pi
            self.Phi[3] = (0.5 - phi1_) * 2 * np.pi
        
        if self.t_count_ >= 200:
            self.t_count_ = 0
            if tau == 0:
                self._t = 0.5
            else:
                self._t = 0.4


        self.update_rotation_matrix()
    

    def step(self):
        if self.count_ > 400:
            self.mu_ = 1
            
        self.count_  = self.count_ + 1

        if self.count_ > 1200 and self.count_ <= 1400:
            self.transit_gait(tau=0)
        
        if self.count_ > 1800 and self.count_ <= 2000:
            self.transit_gait(tau=1)
        
        for _ in range(5):
            for i in np.arange(0, self.leg_num):
                r_pow = (self.leg_x[i] - self.u1) ** 2 + (self.leg_y[i] - self.u2) ** 2
                W = math.pi / (self._beta*self._t*(math.exp(-self._a*self.leg_y[i]) + 1)) + math.pi / ((1-self._beta)*self._t*(math.exp(self._a*self.leg_y[i]) + 1))
                V = np.matmul(np.array([[self._alpha * (self.mu_ - r_pow), - W], [W, self._alpha * (self.mu_ - r_pow)]]),
                            np.array([[self.leg_x[i] - self.u1], [self.leg_y[i] - self.u2]])) + \
                    np.matmul(self.R_cell[0, i], np.array([[self.leg_x[0] - self.u1], [self.leg_y[0] - self.u1]])) + \
                    np.matmul(self.R_cell[1, i], np.array([[self.leg_x[1] - self.u2], [self.leg_y[1] - self.u2]])) + \
                    np.matmul(self.R_cell[2, i], np.array([[self.leg_x[2] - self.u1], [self.leg_y[2] - self.u2]])) + \
                    np.matmul(self.R_cell[3, i], np.array([[self.leg_x[3] - self.u1], [self.leg_y[3] - self.u2]]))
                
                self.leg_x[i] = self.leg_x[i] + V[0, 0] * self.t_step
                self.leg_y[i] = self.leg_y[i] + V[1, 0] * self.t_step

        for i in range(0, self.leg_num):
            self.point_x[i] = self.leg_x[i]
            
            self.point_y[i] = self.leg_y[i]
        
            if self.leg_y[i] > 0:
                self.point_y[i] = 0
            else:
                self.point_y[i] = -self.leg_y[i]
            

        return np.concatenate([[h, k] for h, k in zip(self.point_x, self.point_y)])


if __name__ == '__main__':
    cpg = CPG(0)
    step_num = 1800
    
    plt.rcParams.update({'font.size': 20})

    fig1 = plt.figure(figsize=(9, 6))
    plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.5)

    phases = np.stack(np.array([cpg.step() for _ in range(step_num)]), axis=1)
    
    ax = plt.subplot(4, 1, 1)
    leg_labels = ['FL', 'FR', 'HL', 'HR']
    for i in range(4):
        ax.plot(np.arange(0, step_num) * 0.005, phases[2 * i, :], linewidth=2, label=leg_labels[i])
    
    ax.set_xlim(0,step_num * 0.005)
    ax.legend(prop={'size': 14}, loc= 'lower right')
    
    plt.show()

代码实现了从静止到行走(walk)到小跑(trot)再到飞奔(gallop)步态的转换。具体实现细节和解释有时间再写👌。

 相关文章:raisimGymTorch的使用-CSDN博客

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

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

相关文章

今年春节,德施曼成“春晚御用”智能锁,亮相总台春晚直播间

总台春晚&#xff0c;是每年春节期间的最大热点。 今年除夕夜&#xff0c;高端智能锁品牌德施曼&#xff0c;不仅成为“春晚御用”智能锁&#xff0c;还将旗下的哨兵猫眼智能锁&#xff0c;卖到了总台春晚的直播间里。龙年春节&#xff0c;德施曼智能锁携手小红书《大家的春晚》…

Quorum NWR算法,鱼和熊掌也可兼得

众所周知在分布式系统中CAP&#xff0c;一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;、分区容错性&#xff08;Partition Tolerance&#xff09;三个指标不可兼得&#xff0c;只能在三个指标中选择两个。假如此时已经实现了一套AP型…

element ui表格手写拖动排序

效果图&#xff1a; 思路&#xff1a; 重点在于&#xff1a;拖动行到某一位置&#xff0c;拿到这一位置的标识&#xff0c;数据插入进这个位置 vueuse的拖拽hooks useDraggable 可以用&#xff1b;html5 drag能拖动行元素&#xff1b;mounsedown、mounsemove时间实现拖拽 页…

Linux下代码的运行

在Windows环境下&#xff0c;我们代码都是在集成开发环境下运行&#xff0c;也就是说代码的编辑、编译、调试、运行都在一个软件上&#xff0c;而在Linux环境下这些都是分开执行的。 Linux编辑器-vim vim是一款多模式编辑器&#xff0c;vim有很多模式&#xff0c;最常用的三个…

完美运营的最新视频打赏系统及附带教程

(购买本专栏可免费下载栏目内所有资源不受限制,持续发布中,需要注意的是,本专栏为批量下载专用,并无法保证某款源码或者插件绝对可用,介意不要购买) 优于市面上95%的打赏系统,与其他打赏系统相比,功能更加强大,完美运营且无bug。支付会调、短链接生成、代理后台、价…

处理SERVLET中的错误和异常

处理SERVLET中的错误和异常 应用服务器服务客户机请求时可能会遇到一些问题,如找不到所请求的资源或运行中的servlet引发异常。例如,在线购物门户中如果用户选择了当前缺货的物品要放入购物车中,就会出现问题, 这种情况下,浏览器窗口中将显示错误消息。您可以在servlet中…

cesium系列篇:Entity vs Primitive 源码解析(从Entity到Primitive)02

上篇文章中&#xff0c;我们介绍了使用viewer.entities.add添加entity之后的信号传递以及最后entity对象被传递到GeometryVisualizer&#xff1b; 这篇文章&#xff0c;我们则介绍如何在逐帧渲染的过程中根据GeometryVisualizer中的entity对象创建相应的primitive 这是下文中…

C++ 动态规划 树形DP 没有上司的舞会

Ural 大学有 N 名职员&#xff0c;编号为 1∼N 。 他们的关系就像一棵以校长为根的树&#xff0c;父节点就是子节点的直接上司。 每个职员有一个快乐指数&#xff0c;用整数 Hi 给出&#xff0c;其中 1≤i≤N 。 现在要召开一场周年庆宴会&#xff0c;不过&#xff0c;没有职…

那些 C语言指针 你不知道的小秘密 (3)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 我会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能…

【从0上手Cornerstone3D】如何使用CornerstoneTools中的工具之同步器

同步器&#xff08;Synchronizers&#xff09;可以使多个视图同步响应同一个工具的操作&#xff0c;例如我们在MPR视图下&#xff0c;同步操作三个视图的缩放程度、windowLevel等等 一个同步器必须需要以下几个部分才可以执行 一个监听事件&#xff08;什么情况下触发同步&…

STL之stack+queue的使用及其实现

STL之stackqueue的使用及其实现 1. stack&#xff0c;queue的介绍与使用1.1stack的介绍1.2stack的使用1.3queue的介绍1.4queue的使用 2.stack&#xff0c;queue的模拟实现2.1stack的模拟是实现2.2queue的模拟实现 3.总结 所属专栏&#xff1a;C“嘎嘎" 系统学习❤️ &…

【Spring】springmvc如何处理接受http请求

目录 ​编辑 1. 背景 2. web项目和非web项目 3. 环境准备 4. 分析链路 5. 总结 1. 背景 今天开了一篇文章“SpringMVC是如何将不同的Request路由到不同Controller中的&#xff1f;”&#xff1b;看完之后突然想到&#xff0c;在请求走到mvc 之前服务是怎么知道有请求进来…

[BUUTF]-PWN:wdb2018_guess解析

查看保护 查看ida 这道题并不复杂&#xff0c;只是要注意一点细节 完整exp&#xff1a; from pwn import* from LibcSearcher import* pprocess(./guess) premote(node5.buuoj.cn,28068) puts_got0x602020payloadba*0x128p64(puts_got) p.sendlineafter(bPlease type your gu…

基于语义解析的知识图谱问答系统

目录 前言1 背景介绍2 语义解析的核心技术2.1 自然语言处理&#xff08;NLP&#xff09;2.2 语义表示学习2.3 实体关系抽取 3 语义解析的基本步骤3.1 短语检测3.2 资源映射3.3 语义组合3.4 逻辑表达式生成 4 处理与知识图谱无关的问句4.1 Bridging技术4.2 确定谓词4.3 Paraphra…

杨中科 配置系统

1、配置系统入门 说明 1、传统Web.config配置的缺点&#xff0c;之前DI讲到过 2、为了兼容&#xff0c;仍然可以使用Web.config和ConfigurationManager类&#xff0c;但不推荐。 3、.NET 中的配置系统支持丰富的配置源&#xff0c;包括文件(json、xml、ini等)、注册表、环境变…

Redis保证数据不丢失的手段

Redis 保证数据不丢失的主要手段有两个&#xff1a; 持久化集群运行 我们分别来看它们两的具体实现细节。 # 1.Redis 持久化 持久化是指将数据从内存中存储到持久化存储介质中&#xff08;如硬盘&#xff09;的过程&#xff0c;以便在程序重启或者系统崩溃等情况下&#xf…

1898_野火FreeRTOS教程阅读笔记_链表操作

1898_野火FreeRTOS教程阅读笔记_链表操作 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 新的节点的插入&#xff0c;影响到的是链表中最后一个元素的后继以及当前被插入元素的前驱、后继以及归属属性。具体的操作效果为&#xff1a;新的节点更新自己的前…

101. 对称二叉树 - 力扣(LeetCode)

题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 题目示例 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 解题思路 首先想清楚&#xff0c;判断对称二叉树要比较的是哪两个节点&#xff0c;要比较的可不是左右节点&#xff01; 对于…

SAP-PS-001-006问题预算占用与订单实际金额不一致

前言 PS模块最复杂的业务场景主要就是ETO&#xff08;Engineering-To-Order&#xff09;&#xff0c;也就是边设计边生产边采购的三边业务。 意味着从前端设计开始的成本就已经要进行收集&#xff0c;其次对于大型非标设备的生产发货只是一个环节&#xff0c;发货后还会涉及到现…

Java项目maven打包的包名设置(finalname标签的使用)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…