当前位置: 首页 > article >正文

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

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.kler.cn/news/232927.html

相关文章:

  • 春节:当代发展及创新传承
  • 揭开Markdown的秘籍:标题|文字样式|列表
  • c#cad 创建-圆(二)
  • 飞天使-k8s知识点13-kubernetes散装知识点2-statefulsetdaemonset
  • Red Panda Dev C++ Maker 使用说明
  • 攻防世界 CTF Web方向 引导模式-难度1 —— 1-10题 wp精讲
  • Git远程仓库的使用(Gitee)及相关指令
  • 【初中生讲机器学习】6. 分类算法中常用的模型评价指标有哪些?here!
  • 《游戏引擎架构》 -- 学习2
  • curl8.6.0 - CURLE_PEER_FAILED_VERIFICATION
  • Linux——进程间通信:管道
  • VUE学习——事件修饰符
  • npm淘宝镜像源换新地址
  • 如何使用Python + 百度翻译API 自动大批量免费翻译Excel文件中的外语内容
  • Modelsim10.4安装
  • 1123. 铲雪车(欧拉回路)
  • 目标检测 | 卷积神经网络(CNN)详细介绍及其原理详解
  • P59---第二阶段B C 相电流
  • 【Kotlin】Kotlin基本数据类型
  • Python 数据分析库之polars使用详解
  • 【语音合成】中文-多情感领域-16k-多发音人
  • 以用户为中心,酷开科技荣获“消费者服务之星”
  • 腾讯云游戏服务器配置有哪些?
  • 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Video媒体组件
  • 猫头虎分享已解决Bug || CPU过载(CPU Overload):HighCpuUsageWarning, CpuOverloadException
  • 2022年通信工程师初级 实务 真题
  • ElasticSearch 8.x 使用 High Level Client 以 HTTPS 方式链接,SSL 证书、主机名验证器 各是什么,如何忽略
  • 通过遵循最佳做法来提高 EDA 和 HPC 应用程序的 Azure NetApp 文件性能
  • Spring Data Envers 数据审计实战2 - 自定义监听程序扩展审计字段及字段值
  • linux(redhat)重置root密码