栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Python

fabrik 算法的python 实现

Python 更新时间:发布时间: 百科书网 趣学号

IK 运动动力学逆运算的快速,简单迭代算法FABRIK 介绍了算法,现在介绍python 实现算法。

这是一个无约束单链fabrik 算法实现。这个也是有约束和多链的算法基础。

代码放置在

https://github.com/liwenz/Fabrik

这里主要介绍使用方法,代码你就直接看,也不复杂。

 Fabrik 算法的一个非常小而灵活的实现。 适用于动画、机器人或其他优化问题。 这个模块是用python编写的。

fabrik.py : fabrik 类,它解决不受约束的 ik 单链。它可以是 2D、3D 或 nD

init:输入 ik init 位置和 marginOfError。

distance:计算两点之间的距离

compute:输入新的终点并获得 fabrik 结果。

ComputeDiff:输入新端点的差值并得到 fabrik 结果。

calAngle:获取当前角度。

isReachable:检查结果是否可能。

test.py:这是一个演示。 用两种方式构造点数组,然后 fabrik ,打印结果

dog.py 机器狗的单腿计算演示获取结果角度数组

dog4.py 机器狗的4条腿计算demo得到结果数组

这里附上fabrik.py ,其他可到github.com/liwenz/fabrik 查看下载

# -*- coding: utf-8 -*-
"""
Created on Wed Sep 22 13:26:39 2021
@author: zeng_
"""

import numpy as np
import math

class FabrikSolver:
    """ 
        An inverse kinematics solver in Fabrik Algorithm.
    """
    def __init__(self, _points, _marginOfError=0.01):
        self.points=np.copy(_points)
        self.marginOfError=_marginOfError
        self.ndim=self.points.ndim
        self.number=int(self.points.size/self.ndim)
        self.length=np.zeros(self.number-1,dtype=float)
        self.angle=np.zeros(self.number-1,dtype=float)
        #print('ndim= ',self.ndim)
        #print('number= ',self.number)

        self.maxLenth=0.0
        for i in range(self.number-1):
            self.length[i] = self.distance(self.points[i],self.points[i+1])
            self.maxLenth+=self.length[i]
            #print(self.length[i])
        #print('maxlenth= ',self.maxLenth)
    def distance(self,a,b):
        dist=0.0
        for i in range(self.ndim):
            dist=dist+(a[i]-b[i])*(a[i]-b[i])
        dist=math.sqrt(dist)
        return dist
    def CalAngle(self):
        for i in range(self.number-1):
            p=self.points[i+1]-self.points[i]
            self.angle[i]=math.atan2(p[1], p[0])*180/math.pi
        return self.angle



    def Backword(self):
        #print("backword")
        self.points[self.number-1]=self.target
        for i in range(self.number-1):
            q=self.number-1-i
            l=self.distance(self.points[q], self.points[q-1])
            r=self.length[q-1]/l
            #print(i,q,l,r)
            self.points[q-1]=self.points[q-1]*r+self.points[q]*(1-r)
        #print(self.points)
        
    def Forword(self):
        self.points[0]=np.zeros(self.ndim,dtype=float)
        #print("forword")
        for i in range(self.number-1):
            q=i+1
            l=self.distance(self.points[q], self.points[q-1])
            r=self.length[q-1]/l
            #print(i,q,l,r)
            self.points[q]=self.points[q]*r+self.points[q-1]*(1-r)
        #print(self.points)
    def Compute(self,target):
        self.target=target
        print("target= ",self.target)
        if(not(self.isReachable())):
            print("is Not Reachable")
            return 100
        deviate=10000
        while(deviate>self.marginOfError):
            self.Backword()
            self.Forword()
            deviate=self.distance(self.points[self.number-1],self.target)
            #print('deviate= ',deviate)
        return deviate
    def ComputeDiff(self,targetDiff):
        return self.Compute(targetDiff+self.points[self.number-1])
    
    def isReachable(self):

        return (self.maxLenth>=self.distance(self.points[0],self.target))

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/294449.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号