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

北京网站开发企业WordPress多站点同步设置

北京网站开发企业,WordPress多站点同步设置,网站开发运行环境论文,松原网站建设哪家专业目录 一、前言二、fabrik 算法三、python实现结论PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源ps3.wifi小车控制相关文章资源 一、前言 我们用blender等3D动画软件时,会用到骨骼的动画,通过逆向IK动力学…

目录

  • 一、前言
  • 二、fabrik 算法
  • 三、python实现
  • 结论
  • PS.扩展阅读
    • ps1.六自由度机器人相关文章资源
    • ps2.四轴机器相关文章资源
    • ps3.移动小车相关文章资源
    • ps3.wifi小车控制相关文章资源

一、前言

我们用blender等3D动画软件时,会用到骨骼的动画,通过逆向IK动力学,可以实现控制少量点,就能控制一个复杂的骨架运动。这种IK动力学几乎是实时的,非常的高效。这种IK动力学算法的代表是fabrik 算法,该算法应被用于UE虚幻引擎、Unity等3D软件中。大至效果是,可以实现骨架的目标跟随,而且几乎是“实时”的:
在这里插入图片描述
这种感觉,不就是机械臂的虚拟拖拽吗?是否可以给机械臂的逆解,或者是虚拟化示教带来一些启发,是一个有意思的应用。本篇先来初步研究一下fabrik 算法。

二、fabrik 算法

该算法在文章 FABRIK: A fast, iterative solver for the Inverse Kinematics problem中有详细说明,FABRIK算法是一种用于解决逆运动学问题的启发式方法。它通过迭代地调整关节链,使末端执行器逐渐接近目标位置。与传统方法相比,FABRIK算法不需要使用旋转角度或矩阵,而是通过在线段上定位点来找到每个关节的位置,这使得它在计算上更加高效,并且能够产生视觉上现实的关节姿势。
在这里插入图片描述

三、python实现

网上已经有很多实现的python算法,这里,主要是利用实现的3D算法,实现在matplot中的IK,即,任意点击3D坐标点,实现IK,骨架的末端移动到目标点,就像开始的blender一样。
在这里插入图片描述
首先,我们需要导入一些必要的Python库,包括NumPy、Math、Matplotlib等,用于数学运算和图形绘制。

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
import re

单位向量函数
定义了一个函数 unitVector,它接受一个向量作为输入,并返回该向量的单位向量。

def unitVector(vector):return vector / np.linalg.norm(vector)

Segment3D 类用于存储逆运动学链的一部分。它接受参考点坐标、段长度和初始角度作为参数,并计算出该段的新坐标。

class Segment3D:def __init__(self, referenceX, referenceY, referenceZ, length, zAngle, yAngle):self.zAngle = zAngleself.yAngle = yAngleself.length = lengthdeltaX = math.cos(math.radians(zAngle)) * lengthdeltaY = math.sin(math.radians(zAngle)) * lengthdeltaZ = math.sin(math.radians(yAngle)) * lengthnewX = referenceX + deltaXnewY = referenceY + deltaYnewZ = referenceZ + deltaZself.point = np.array([newX, newY, newZ])

FabrikSolver3D 类是FABRIK算法的核心,它初始化了一个3D逆运动学求解器,并提供了添加段、检查可达性、迭代求解和绘图等功能。

        
class FabrikSolver3D:""" An inverse kinematics solver in 3D. Uses the Fabrik Algorithm."""def __init__(self, baseX=0, baseY=0, baseZ=0,  marginOfError=0.01):# Create the base of the chain.self.basePoint = np.array([baseX, baseY, baseZ])# Initialize empty segment array -> [].self.segments = []# Initialize length of the chain -> 0.self.armLength = 0# Initialize the margin of error.self.marginOfError = marginOfErrorself.targetpoint=Noneself.fig = plt.figure()self.ax1 = self.fig.add_subplot(111, projection="3d")self.mousep=Nonedef addSegment(self, length, zAngle, yAngle):if len(self.segments) > 0:segment = Segment3D(self.segments[-1].point[0], self.segments[-1].point[1], self.segments[-1].point[2], length, zAngle + self.segments[-1].zAngle, self.segments[-1].yAngle + yAngle)else:# Maak een segment van de vector beginpoint, lengte en hoek.segment = Segment3D(self.basePoint[0], self.basePoint[1], self.basePoint[2], length, zAngle, yAngle)# Voeg lengte toe aan de totale armlengte.self.armLength += segment.length# Voeg de nieuwe segment toe aan de list.self.segments.append(segment)def isReachable(self, targetX, targetY, targetZ):if np.linalg.norm(self.basePoint - np.array([targetX, targetY, targetZ])) < self.armLength:return Truereturn Falsedef inMarginOfError(self, targetX, targetY, targetZ):if np.linalg.norm(self.segments[-1].point - np.array([targetX, targetY, targetZ])) < self.marginOfError:return Truereturn False     def iterate(self, targetX, targetY, targetZ):target = np.array([targetX, targetY, targetZ])# Backwards.for i in range(len(self.segments) - 1, 0, -1):if i == len(self.segments) - 1:self.segments[i-1].point = (unitVector(self.segments[i-1].point - target) * self.segments[i].length) + targetelse:self.segments[i-1].point = (unitVector(self.segments[i-1].point - self.segments[i].point) * self.segments[i].length) + self.segments[i].point# Forwards.for i in range(len(self.segments)):if i == 0:self.segments[i].point = (unitVector(self.segments[i].point - self.basePoint) * self.segments[i].length) + self.basePointelif i == len(self.segments) - 1:self.segments[i].point = (unitVector(self.segments[i-1].point - target) * self.segments[i].length * -1) + self.segments[i-1].pointelse:self.segments[i].point = (unitVector(self.segments[i].point - self.segments[i-1].point) * self.segments[i].length) + self.segments[i-1].pointdef compute(self, targetX, targetY, targetZ):if self.isReachable(targetX, targetY, targetZ):while not self.inMarginOfError(targetX, targetY, targetZ):self.iterate(targetX, targetY, targetZ)   self.targetpoint=[targetX, targetY, targetZ]else:print('Target not reachable.')sys.exit()def plot(self, save=False, name="graph"):self.ax1.clear()  # 清除当前轴ax1=self.ax1# Plot arm.for i, segment in enumerate(self.segments):#ax1.scatter(segment.point[2], segment.point[0], segment.point[1], c='b')ax1.scatter(segment.point[0], segment.point[1], segment.point[2], c='b')if i > 0:  # Connect to the previous segmentax1.plot([self.segments[i-1].point[0], segment.point[0]],[self.segments[i-1].point[1], segment.point[1]],[self.segments[i-1].point[2], segment.point[2]], 'b-')"""ax1.plot([self.segments[i-1].point[2], segment.point[2]],[self.segments[i-1].point[0], segment.point[0]],[self.segments[i-1].point[1], segment.point[1]], 'b-')"""# Connect the last segment to the base point"""ax1.plot([self.basePoint[2], self.segments[0].point[2]],[self.basePoint[0], self.segments[0].point[0]],[self.basePoint[1], self.segments[0].point[1]], 'b-')"""ax1.plot([self.basePoint[0], self.segments[0].point[0]],[self.basePoint[1], self.segments[0].point[1]],[self.basePoint[2], self.segments[0].point[2]], 'b-')# Start point#ax1.scatter(self.basePoint[2], self.basePoint[0], self.basePoint[1], c='g')ax1.scatter(self.basePoint[0], self.basePoint[1], self.basePoint[2], c='g')ax1.scatter(self.targetpoint[0],self.targetpoint[1],self.targetpoint[2], c='r',alpha=0.6, s=100)ax1.set_ylabel('y-axis')ax1.set_zlabel('z-axis')ax1.set_xlabel('x-axis')# Set the view angle so that the z-axis is pointing upwardsax1.view_init(elev=45., azim=45.)plt.pause(0.01)def extract_coordinates(self,s):# 使用正则表达式匹配x, y, z的值# 注意:负号前面加上了反斜杠进行转义# 使用正则表达式提取实数值,包括负号pattern = r'−?\d+\.\d+'matches = re.findall(pattern, s)values = [float(match.replace('−', '-')) for match in matches]x, y, z=values return x, y, zdef show(self):self.plot()self.fig.canvas.mpl_connect('button_press_event', self.on_click)  # 连接点击事件self.fig.canvas.mpl_connect('motion_notify_event', self.on_motion) plt.show()def on_motion(self,event):if event.inaxes is not None:x, y = event.xdata, event.ydatasting = self.ax1.format_coord(x, y)              x,y,z=self.extract_coordinates(sting)#print(x,y,z) self.mousep=(x,y,z)def on_click(self, event):# 检查点击事件是否在坐标轴内if event.inaxes is not None:print(f'Clicked on axis {event.inaxes}')# 触发你的函数print(self.mousep)if not type(self.mousep) == type(None):           x,y,z=self.mousepprint("compute")self.compute(x, y, z)self.plot()# 获取点击的坐标值#self.compute(x, y, z)# 重绘图形#

可以通过如下步骤实现逆解:

  • 添加关节段:通过addSegment方法,我们可以为机械臂添加多个关节段,每个关节段都有自己的长度和初始角度。

  • 检查可达性:isReachable方法检查目标位置是否在机械臂的可达范围内。

  • 迭代计算:iterate方法执行一次FABRIK算法迭代,调整关节位置以接近目标。

  • 绘图显示:plot方法用于在3D空间中绘制机械臂的当前状态,show方法则显示最终的图形界面,并允许用户通过点击来选择目标位置。

  • 事件处理:on_click和on_motion方法用于处理用户的点击和鼠标移动事件,以便动态地调整目标位置。

        if __name__ == "__main__":        arm = FabrikSolver3D()    arm.addSegment(0, 0, 0)arm.addSegment(50, 0, 0)arm.addSegment(50, 0, 0)arm.addSegment(50, 0, 0)arm.addSegment(50, 0, 0)arm.compute(50, 50, 100)    arm.show()

在这里插入图片描述

结论

通过这个Python实现,我们可以看到FABRIK算法在解决3D逆运动学问题中的强大能力。它不仅能够快速找到解决方案,还能够实时响应用户的交互,这在模拟和实际应用中都是非常有价值的。接下来我们尝试丰富这个算法,在各关节添加约束,并应用到6轴机械臂的IK计算中,看看能否获得预期效果。

[------------本篇完-------------]

PS.扩展阅读

————————————————————————————————————————

对于python机器人编程感兴趣的小伙伴,可以进入如下链接阅读相关咨询

ps1.六自由度机器人相关文章资源

(1) 对六自由度机械臂的运动控制及python实现(附源码)
在这里插入图片描述

(2) N轴机械臂的MDH正向建模,及python算法
在这里插入图片描述

ps2.四轴机器相关文章资源

(1) 文章:python机器人编程——用python实现一个写字机器人
在这里插入图片描述

在这里插入图片描述

(2)python机器人实战——0到1创建一个自动是色块机器人项目-CSDN直播

(3)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(3)博文《我从0开始搭建了一个色块自动抓取机器人,并实现了大模型的接入和语音控制-(上基础篇)》的vrep基础环境
(4)实现了语音输入+大模型指令解析+机器视觉+机械臂流程打通
在这里插入图片描述
在这里插入图片描述

ps3.移动小车相关文章资源

(1)python做了一个极简的栅格地图行走机器人,到底能干啥?[第五弹]——解锁蒙特卡洛定位功能-CSDN博客
(2) 对应python资源:源码地址
在这里插入图片描述
在这里插入图片描述

(3)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(上篇)_agv编程-CSDN博客
(4)python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(下篇)_agv路线规划原则python-CSDN博客
对应python及仿真环境资源:源码链接
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ps3.wifi小车控制相关文章资源

web端配套资源源代码已经上传(竖屏版),下载地址
仿真配套资源已经上传:下载地址
web端配套资源源代码已经上传(横屏版),下载地址

在这里插入代码片
http://www.yayakq.cn/news/724832/

相关文章:

  • 好的网站建设专业公司网站设计公司石家庄
  • 做网站手机浏览全屏专业制作
  • 长沙网站设计哪家好手机网站建设沈阳
  • 泊头网站建设的有哪些用html做的网站加背景音乐
  • 网站流量指的是什么意思wordpress做流量站
  • 2核4g 1m做网站oa系统登录网址
  • 开发app的网站有哪些工信部网站登陆
  • 网站怎么做虚拟连接泰州网站建设公司哪个好
  • 动易网站系统广告影视制作谁家好
  • 网站建设投标书怎么制作宁波手机网站建设
  • 一个人制作网站手机网站建站费用
  • 网站主题的分类标准化信息网站建设与应用
  • 南京网站维护公司手机优化专家
  • 吕梁网站建设四川省建设注册中心网站
  • n怎样建立自己的网站做微网站哪家好
  • h5网站建设方案.doc动漫设计与制作都学什么
  • 该模板尚未授权此网站免费动漫
  • 电商网站建设目标分析的方法wordpress渐隐渐现页面过渡效果
  • 西安网站建设推广公司网站设计一个月多少钱
  • 河东建设局网站营销策划书模板范文
  • 温州网站建设外包wordpress友情链接直接留空白代码
  • 中国建设银行网站易方达消费微信如何做有趣的短视频网站
  • iphone手机网站建设网站网址查询 优帮云
  • 魔方 网站建设 有限公司北京市朝阳区网站制作
  • 网站怎么做备案变更html5网站引导页模板
  • 哪家公司建设网站好调用wordpress数据
  • 那里有正规网站开发培训学校网站如何做下载链接
  • 上海正规做网站公司软文推广500字
  • 国内三大电商平台分析报告seo页面优化平台
  • 辽宁天一建设有限责任公司网站网站为什么会出现死链