概述

IK(逆向运动学)在许多情况下都很有用,从程序动画到动画的小调整。简单地说,当您希望将分层结构的尖端定位在已知位置,并且需要计算父关节的所有旋转以实现这一点时,将使用IK。

示例包括:移动一只手来拾取物体,或调整一只脚,使其始终接触地面,无论倾斜程度如何。

术语

了解一些在谈论反向运动学时使用的术语是很有帮助的,这样你就能更好地理解所说的内容。

  • 解算器树中最上部的节点称为基本节点或根节点。
  • 需要移动到特定目标位置(例如:人的手)的节点称为末端效应器。
  • 多个子节点从中分支的关节称为子基节点。
  • IK解算器在节点的单个“字符串”(称为链)上工作效率最高。
  • 整个结构(在人类双手的情况下)被称为链树。

末端效应器

效应器用于设置节点的目标位置和旋转。可以通过将IKEffector组件附加到节点来创建一个。

Node* handNode = modelNode->GetChild("Hand.R", true);IKEffector* effector = handNode->CreateComponent<IKEffector>();  // C++
IKEffector@ effector = handNode.CreateComponent("IKEffector");   // AngelScript
local effector = handNode:CreateComponent("IKEffector")          -- Lua

然后,可以使用IKEeffector::SetTargetPosition为效应器指定目标位置(例如,苹果的位置),也可以告诉效应器使用IKEeffect::SetTargetNode自动跟踪节点的位置。

effector->SetTargetPosition(appleNode->GetWorldPosition());  // C++
effector.targetPosition = appleNode.worldPosition;           // AngelScript
effector.targetPosition = appleNode.worldPosition            -- Lua

如果启用,还可以告诉效应器尝试使用IKEffector::SetTargetRotation匹配目标旋转。如果您希望手指向与苹果相关的特定方向,则此功能非常有用(需要在解算器中启用此功能,这将在下面进一步讨论)。

目标位置和旋转都在全局空间中设置。

另一个重要参数是链长度IKEffector::SetChainLongth。链长度为1表示单个节段或“骨骼”受到影响。手臂和腿通常使用值2(因为您只想求解手臂而不是整个身体)。默认值为0,这意味着直接到基本节点的所有节点都会受到影响。

effector->SetChainLength(2); // Humans have two bones in their arms
effector.chainLength = 2;    // AngelScript
effector.chainLength = 2     -- Lua

效应器有一个权重参数(使用IKEffector::SetWeight),指示它们对要解决的树的影响程度。您可以利用这一点平滑地过渡到IK解决方案中和从IK解决方案过渡。当角色开始拾取对象并希望从动画平滑切换到IK时,将需要此选项。

effector->SetWeight(SomeSplineFunction());  // C++
effector.weight = SomeSplineFunction();     // AngelScript
effector.weight = SomeSplineFunction();     -- Lua

如果您使用了权重参数,您可能已经注意到它会导致目标位置的线性插值。这在有机生物身上看起来很糟糕,特别是当解决的树与原始树相距很远时。您可以考虑启用nlrp,这会导致权重围绕下一个子基关节旋转。可以使用IKEffector::SetFeature启用此功能。

effector->SetFeature(IKEffector::WEIGHT_NLERP, true);  // C++
effector.WEIGHT_NLERP = true;                          // AngelScript
effector.WEIGHT_NLERP = true                           -- Lua

请注意,脚本绑定在这方面的工作方式略有不同。这些特征可以作为属性直接在效应器对象上启用/禁用,而不必调用SetFeature。这是为了方便(但可能会因脚本API不一致而在将来更改)。

求解器

解算器负责基于附加的效应器及其设置计算解决方案。

请注意,解算器只会影响子树中的节点。这意味着,如果将IKEeffector附加到IKSolver节点的父节点,则解算器将忽略该效应器。

可以通过将IKSolver组件附加到节点来创建解算器:

IKSolver* solver = modelNode->CreateComponent<IKSolver>();  // C++
IKSolver@ solver = modelNode.CreateComponent("IKSolver");   // AngelScript
local solver = modelNode:CreateComponent("IKSolver")        -- Lua

您首先要做的是选择合适的算法。在撰写本文时,有3种算法可供选择,您应该按照此处列出的顺序选择它们。

  • ONE_BONE:专门的解算器,用于将对象指向目标位置(例如眼睛、头部等)
  • TWO_BONE:使用三角法计算直接解的专用解算器,特别是针对两个骨骼结构(手臂、腿)
  • FABRIK:一个通用的求解器,能够解决任何你能解决的问题。它使用迭代算法,因此比两个专用算法慢一点。应用于具有3个或更多骨骼的结构,或具有多个末端效应器的结构。

您可以使用以下方法设置算法:

solver->SetAlgorithm(IKSolver::FABRIK);  // C++
solver.algorithm = IKAlgorithm::FABRIK;  // AngelScript
solver.algorithm = IKSolver.FABRIK       -- Lua

如果选择了迭代算法,那么可能还需要调整最大迭代次数和容差。FABRIK收敛速度非常快,在20次或更少的迭代中运行良好。有时,您甚至只需要5次迭代就可以成功。公差指定允许末端效应器与其目标之间的最大距离。显然,设置的公差越小,需要的迭代次数就越多。公差的良好起始值约为所求解链的100倍(例如,如果链长2个单位,则将公差设置为0.02)。

solver->SetMaximumIterations(20); // Good starting value for FABRIK
solver->SetTolerance(0.02);       // Good value is 100th of your chain length.solver.maximumIterations = 20;    // AngelScript
solver.tolerance = 0.02;solver.maximumIterations = 20     -- Lua
solver.tolerance = 0.02

请注意,如果选择了直接解算器(例如TWO_BONE或ONE_BONE),则这些设置不会起作用。

解算器功能

解算器上有许多功能可以启用/禁用,所有这些功能都可以使用IKSolver::SetFeature进行切换,并使用IKSolver::GetFeature进行检查。您可以随时查看IKSolver::Feature的文档,了解每个功能的详细描述。

自动解决

默认情况下,解算器将处于自动解算模式。这意味着它将自动为您执行其计算,以响应E_SCENEDRAWABLEUPDATEFINISHED。您所要做的就是创建效应器,设置它们的目标位置,然后让解算器处理其余的。您可以通过禁用AUTO_SOLVE功能来覆盖此行为,在这种情况下,您必须手动调用IKSolver::SOLVE才能执行任何操作。如果您希望在动画更新后,但在计算反向运动学之前“钩住”,则可能需要此选项。

solver->SetFeature(IKSolver::AUTO_SOLVE, false);  // C++
solver.AUTO_SOLVE = false;                        // AngelScript
solver.AUTO_SOLVE = false                         -- Lua

下面是如何手动调用解算器。

// C++
void MyLogic::Setup()
{SubscribeToEvent(GetScene(), E_SCENEDRAWABLEUPDATEFINISHED, URHO3D_HANDLER(MyLogic, HandleSceneDrawableUpdateFinished));
}
void MyLogic::HandleSceneDrawableUpdateFinished(StringHash eventType, VariantMap& eventData)
{GetComponent<IKSolver>()->Solve();
}// AngelScript
void Setup()
{SubscribeToEvent("SceneDrawableUpdateFinished", "HandleSceneDrawableUpdateFinished")
}
void HandleSceneDrawableUpdateFinished(StringHash eventType, VariantMap& eventData)
{GetComponent("IKSolver").Solve()
}// Lua
function Setup()SubscribeToEvent("SceneDrawableUpdateFinished", "HandleSceneDrawableUpdateFinished")
end
function HandleSceneDrawableUpdateFinished(eventType, eventData)GetComponent("IKSolver"):Solve()
end

IKSolver::JOINT_ROTATIONS

solver->SetFeature(IKSolver::JOINT_ROTATIONS, false);  // C++
solver.JOINT_ROTATIONS = false;                        // AngelScript
solver.JOINT_ROTATIONS = false                         -- Lua

如果在蒙皮模型(或需要旋转的节点结构)上使用IK,则应启用此选项。如果您不关心节点旋转,则可以禁用此功能并获得少量性能提升。

禁用时,所有节点都将保持其在世界中的原始方向,只有其位置会更改。

解算器通过将解算的树与原始树进行比较来计算解算收敛后的关节旋转,以此作为计算增量角的方法。然后将它们乘以原始旋转,以获得最终关节旋转。

目标_旋转

solver->SetFeature(IKSolver::TARGET_ROTATIONS, false);  // C++
solver.TARGET_ROTATIONS = false;                        // AngelScript
solver.TARGET_ROTATIONS = false                         -- Lua

启用此选项将导致在求解过程中考虑效应器节点(IKEffector::SetTargetRotation)的方向。这意味着效应器节点将尽可能地匹配目标的旋转。如果目标不在可及范围内或刚好在可及的范围内,则链条将伸出并开始忽略目标旋转,以达到其目标。

禁用此功能会导致IKEffector::SetTargetRotation无效。

UPDATE_ORIGINAL_POSE, UPDATE_ACTIVE_POSE, 和 USE_ORIGINAL_POSE

这些选项很难理解。

解算器实际上存储两棵树,而不是一棵。有一个活动的树,有点像“工作台”。解算器使用活动树作为其初始条件,但也将解写回活动树中(即,在适当位置解算树,而不是克隆树)。

然后是原始树,它在创建过程中设置一次,然后从未更改(至少在默认情况下不会更改)。

您可以控制解算器应将哪棵树用于其初始条件。如果启用USE_ORIGINAL_POSE,则解算器将在解算之前首先将所有位置/旋转从原始树复制到活动树中。因此,如果可以的话,解决方案将倾向于“恢复”到其原始配置。

如果禁用USE_ORIGINAL_POSE,则解算器将使用活动树。活动树将包含上次解决的任何姿势。因此,解决方案将趋于更加“连续”。

非常重要:请注意,除非启用UPDATE_active_POSE(默认情况下启用),否则Urho3D不会更新活动树。如果UPDATE_ACTIVE_POSE被禁用,则任何已移动到IKSolver控制之外的节点都将被有效忽略。因此,如果模型已设置动画,则很可能需要启用此选项。

UPDATE_ORIGINAL_POSE实际上不是必需的,但这里是用于调试的。您可以通过启用此功能或显式调用IKSolver::ApplySceneToOriginalPose来更新原始姿势。

约束

此功能尚未实现,计划在未来发布。

urho3D 运动逆解Inverse Kinematics相关推荐

  1. 机器人运动逆解算IK

    文章目录 Inverse kinematics 基本概念 范例 数学推导 DH模型 坐标系定义 参数定义 坐标变换 Jacobian矩阵 CoppeliaSim 内置模块 范例 构建IK组 外部编程 ...

  2. Stewart平台六自由度运动平台位置逆解实现与仿真研究

    1.内容简介 首先,应用D-H法对六自由度运动平台的运动学进行分析,并在Matlab/Simulink仿真集成环境中建立其位置逆解模型:然后利用Simulink下的SimMechanics工具集搭建好 ...

  3. 实例10:四足机器人运动学逆解可视化与实践

    实例10: 四足机器人运动学逆解单腿可视化 实验目的 了解逆运动学的有无解.有无多解情况. 了解运动学逆解的求解. 熟悉逆运动学中求解的几何法和代数法. 熟悉单腿舵机的简单校准. 掌握可视化逆向运动学 ...

  4. 【机器人学】冗余七自由度机械臂的解析解逆解算法

    冗余七自由度机械臂的解析解逆解算法 参考 论文一 论文二 参考 -[1] An Analytical Solution for a Redundant Manipulator with Seven D ...

  5. 如何实现六轴机械臂的逆解计算?

    1. 机械臂运动学介绍 机械臂运动学 机器人运动学就是根据末端执行器与所选参考坐标系之间的几何关系,确定末端执行器的空间位置和姿态与各关节变量之间的数学关系.包括正运动学(Forward Kinema ...

  6. 仿人型手腕 6R机械臂 D-H参数和运动学逆解

    计算正向运动学通常需要使用D-H参数法对机械臂建模. 第一步: 绘制机械臂模型图 可用手绘机械臂结构简图或者模型图,使用圆柱体代表转动关节和线表示的连杆,当写论文的时候,可以使用PPT或者CAD来绘图 ...

  7. 反向动力学(Inverse kinematics) 学习笔记

    反向动力学(Inverse kinematics) 学习笔记 1 背景 1.1 骨骼动画 将动画分为两个部分:用于绘制外观的蒙皮,以及用于控制动作的骨架(摘自维基百科).这些骨架以树状结构组织,每片骨 ...

  8. 机器人学之运动学笔记【4】—— 逆向运动学(Inverse Kinematics)

    机器人学之运动学笔记[4]-- 逆向运动学(Inverse Kinematics) 1. 逆向求解概念 1.1 了解 1.2 Reachable workspace & Dexterous w ...

  9. 和ur的区别_UR机械臂simscape正逆解仿真

    最近在看相关的课程,把作业做一下,还是蛮有意思的.(课程代码所以涉及版权问题,经过同意后我上传代码) UR机械臂的物理模型文件是根据SolidWorks插件simscape导出的xml文件,课程直接提 ...

最新文章

  1. php截取中文字符串时乱码问题
  2. jasig CAS实现单点登录(数据库认证)
  3. 不同对象的通话是时长​
  4. html5-样式表的使用-初步
  5. java socket 异步回调函数_浅谈socket同步和异步、阻塞和非阻塞、I/O模型
  6. 《CCNA网络技术学习指南》-命令版
  7. 利用JNI调用c++函数
  8. PageAdmin网站建设教程:仿58同城站群实现不同地区Ip跳转不同分站
  9. 数学速算法_计算总是出算?小学数学常用的25种快速口算窍门,学好算数必备...
  10. SCI论文写作是用主动语态好还是被动语态好?
  11. 入门-EdgeBoard赛事专用卡 2023年智能车竞赛完全模型组赛事专用卡
  12. itunes计算机无法启动,解决:Apple移动设备服务无法启动
  13. DBMS_SQL的使用
  14. 手机邮箱怎么注册申请,手机邮箱在哪里找到,电子邮箱怎么弄?
  15. 学了代码之后,对于程序员黑客的区别,我的认识是......
  16. 问题 E: 购买贺年卡(card)
  17. 一分钟实现内网穿透(ngrok服务器搭建)
  18. 蚁剑连接php3,利用中国蚁剑无文件连接 phpstudy 后门方法
  19. 二元置信椭圆r语言_一般加性模型的简介、应用举例及R语言操作
  20. 为知笔记有linux版本吗,为知笔记Linux版

热门文章

  1. 拉卡拉做社区电商,有这些优劣势
  2. Linux随笔16-主从DNS服务搭建以及智能DNS服务搭建、基于CentOS7.6编译安装MySQL-5.7.32
  3. SKlearn中的函数学习总结(持续更新)
  4. springboot+mybatis+新加属性自动加数据库字段
  5. 电脑连接电视的方法---HDMI篇
  6. 全国青少年软件编程(Scratch)等级考试一级考试真题2022年12月——持续更新.....
  7. 怎么将svn服务器上的文件彻底删除,如何彻底删除SVN中的文件和文件夹(附恢复方法)...
  8. android文本框带图片格式,android 带图片的文本框
  9. MacOS-Mac开发和iOS开发的区别
  10. 几万年前,孙悟空的一次删库跑路...