GAMES105-计算机角色动画基础 - P11:Lecture10 Controlling Character - GAMES-Webinar - BV1GG4y1p7fF
好的那欢迎大家来参加我们这个games 105啊,这是应该是我们的第11次课啊,我们其实这次课跟上节课课是一个,就是连接比较紧密的一个两节课,其实主要是讲一讲角色动画里边,特别是基于物理角色动画里边。
我们该如何去驱动角色啊,我们的这个仿真角色去做一些事情啊,当然这个上节课我们主要是讲了一部分,这个控制方面的,就pd control的一些基本知识,我们今天这节课呢,会接着我们上一节课的内容啊。
就是把我们pd control的一些更加细节的一些啊话题,我们今天再稍微多讨论一下,另外呢我们其实上节课也讲到了pd control,我们简单直接去track track一个motion。
我们其实很难去实现一个物理准确的,就是呃我们必须要加一些,比如说virtual false,这个这个hand of god,就这种在柱子上多加一些力,这种方式来实现这个角色的平衡。
但是这种力呢会带来一些不好的效果,那我们其实今天这节课我们会讲一讲,该如何去把这个例去掉,能够让我们的角色生成一个完整的这个啊,就是物理准确的,物理真实的这样的一个动作,那当然我们今天主要是讲两个。
比较简单的方法啊,一个是这个开环控制,也就是feforward控制方面的一些内容,然后另外我们简单讲一些这个feedback控制嗯,就是这个这个如何通过一些简单的策略来实现。
一个原地保持平衡的这么一个控制器,好我们今天主要是讲这些内容,那我们上节课其实已经提到了,关于这个关于这个啊pd control啊,就是所谓的这个比例微分控制器,就是说当我们需要去让一个角色啊。
比如说我一个胳膊,我想让我的这个肘关节转动到某一个角度,那我们通常来讲可以是在,就是我们为了驱动角色运动,我们总是需要加再加一个关节力矩,然后这个关节力矩我们可以通过一个啊。
这么一个简单的一个线性公式来进行计算,那首先前面一部分是我的这个目标的,目标的位置啊,比如说我要把这个肘关节转成90度,那我其实有一个目标的目标的这个角度,就是90度。
然后第二部分呢这个q是我当前的这个角度,然后这两个之间其实代表了,我到我们目标之间的这个偏差,然后用这个偏差成一个比例系数,那其实就得到了我的一个啊需要加多少的力啊,做下来加多少例举这么一个计算。
那另外呢,其实也是为了能够让我们这个跟踪过程能够,更加的这个平瓦啊,更加的这个嗯,因为如果说我们只是单纯的加,根据这个啊偏差去算这个false的话,那我们其实这个角色啊这个胳膊会不可避免的。
它会在那个目标位置附近去震荡,然后为了能够减弱这种震荡的话,通常来讲我们会有一个阻尼项,那就是第二部分,它会根据我当前的速度来减少啊,我需要加的这个大小,那当然pd控制应该是说我们在控制力领域。
这个非常非常简单,而且也是非常非常常用的一类控制策略,其实不只是在角色动画里面,其实想想,就是大家可能已经看到很多这种奇怪的问题,比如说一边放水,一边进水,然后这个时候我们再怎么该。
该怎么去保持这个水位的高度啊,这其实也是可以用pd控制来实现的,另外实际上在工程领域的话,其实大好多好多,我们常见的这种这种机器人,或者感觉更复杂的一些机械,它其实本质上最终还都是pd控制。
然后就是就是说皮筋膜虽然很简单嘛,但是就是一方面很实用,另一方面,其实很多时候我们想要去实现更加复杂的,这种控制的话,我们通常要求我们对这个目标的这个,比如机器人啊,对他的整个动力系统啊。
对它整个的跟环境交互啊,这整个过程我们要足够的了解,才能让我们的模型变得比较精确,但我们在不了解的情况下呢,其实我们很不可避免的要做一些近似,那如果说我们近似到这个某种,这个极限的程度的话。
那其实它就还原成一个一个pd control了,所以说实际上pd control是一个就是很常用的一个,一个一个一个一个控制策略,那当然pd控制其实还有很多的,这个本身还有一些很大的问题。
其实我们上节课也讲到了一个那个,用一个非常简单的一个一个toy model啊,去介绍了一下,就是一个最最最基本的问题,就是pd control,它本质上来说我们需要去计算一个力。
那这个力是是这个跟我当前就是我当前的状态,跟我的目标状态之间的偏差产生一个比例系数,也就意思是说他必须要有这样一个偏差啊,才有这样一个力,假如也就是说没有人没有偏差了,就没有力,那这种情况下。
就在很多情况下,会有一个叫这个稳态误差的这么一个东西,就比如说刚才还是我们那个例子,比如说我这个胳膊,我这胳膊是这样一个状态,我想把这个胳膊这个小臂把它端平,把它端平,但是这个时候我们只要有重力的。
比如这个小臂是在一个水,这个垂直方向上转动的,这样一个嗯这样一个状态,那么因为重力的作用,重力会在这个重心上加一个力矩,那这个力矩会让这个这个小b啊,它会向下去下垂,那为了能够对抗这个力矩的话。
我们必须要加一个关节力矩,那这个关节力矩需要至少在平衡的时候,需要跟这个重力的力矩是保持是一致的,是相同的,那这样才能保持这样一个稳定的状态,但是呢因为我们关节力矩。
我们知道用pd control的时候,如果是我这里出现了力,它大于零,那就说明我的误差一定是一定是大于零的啊,这这是因为我们这个比例公式就是这么定义的,所以实际上,如果说我们把目标位置设置在水平状态。
那么我啊跟踪这个水平状态,因为pd control就跟踪跟踪啊,算了跟踪这个水平状态的话,那这个大小b是肯定不会啊水平的啊,这是其实是一个也是p bd control,一个非常重要的一个一个特点。
那还有另外一个特点呢,其实本质上来说跟第一个特点是相同的,是同样的一个问题啊,就是说因为我总是要有偏差之后,我才能计算力,那计算力之后呢,这个力才会驱动这个角这个物体啊,或者这个角色去产生运动。
所以实际上比如说我这是一个正弦曲线,这个这个点线的这个曲线是一个正弦曲线,如果说我用pd控制,把这个这个曲线上,这个轨迹作为我的这个控制目标,然后用pd控制的话,你通过仿真仿这个生成的这个曲线。
你会发现它通常来讲会比我这个输入的曲线,有一个延后,有时候可以看到,比如说我的输入曲线已经到了一个最高点了,然后我这个仿真的曲线其实会延后一段时间,到达这个最高点,所以总会有这样的一个相位的一个偏差。
当然如果说对一个简单的系统的话,这个相位偏差是多少,我们是可以算出来的,当然这个属于大家有兴趣的话,可以更加了解一些,比如说控制论领域的一些技术知识,当然这里我们只是一个定性的。
就知道这个事情就就可以了,那回到这个回到前面这个问题就是这两种,不管是这个啊所谓的稳态误差,还是我们的这个啊这个相位啊,相位这个这个池岩这个问题,其实本质上都是,因为这个我们是需要根据误差来计算。
我们的这个这个false,所以说从另外一个角度讲,如果说我们知道kb k d control里边前面这一项,前面这一项它其实是一个所谓的这个steffens,所谓的刚性,或者说我们的这个这个增益啊。
就是这个game这一项,他其实在稳态的时候,我们上节课其实也算过,就是包括我们其实就是刚才这个例子,也是很容易得到的,因为这个套在稳态的情况下,它要平衡重力,那重力其实是恒定的对吧,然后为了实现这个套。
我这个误差实际是跟这个,如果在相同的套的情况下,误差跟我的kp是乘这个就他俩乘积一致嘛,所以他俩其实是一个反比关系,有时候如果说我用一个更大的一个kp hien啊。
这种pd control就是kb很大的一个pd control的情况下,那么它在稳态的时候,它其实这个误差会小一点,那从另外一个角度讲,就是包括我们前面提到的,关于这个啊跟踪一个轨迹的时候。
带来这个相位偏差的问题,他其实也是说在我这个kp比较大的时候,这个相位偏偏差也会相对减小一些,但是呢,虽然说感觉好像我们把这个kb调大一点好,就什么问题都解决了,但其实不是这样。
首先是说其实上节课如果大家还有印象的话,我们当时有一个视频啊,我其实播放了一下哎,如果说用不同大小的kp去跟踪一个t pose啊,让这个角色去做t po,你会发现当kb很大的时候。
这个角色动作会显得非常的僵硬啊,就感觉一直挺挺的啊,就是这个这看起来就不是很自然,另外一方面从这个仿真的角度讲,然后比较大的一个kp呢,会带来一些呃仿真上的这个稳定性问题,就比如说我们还是举一个例子啊。
就比如说我们前面在讲这个仿真的时候,我们用了这个例子,就是一个弹簧啊,弹簧有一个进度系数k p那同,但是我们这个在这里边,我其实在这个弹簧车,在额外的多加了一个阻尼的一个东西。
就说这个弹簧除了这个弹性之外呢,它还会根据我这个速度啊,会有一个阻尼力,所以说本质上来说,这个系统它就是一个kpd control,就是一个pd控制器,那当然p控制理器里边。
就是第一项里边的目标值是零啊,我们是假设它是零啊,其实不是零,我们可以同样讨论,只不过把它设成零,相对简单一点,如果说这个东西这样一个物体,它受到pd控制啊的这个控制。
那么实际上我们知道它的false计算是一个,就可以通过这样的一个简单的一个,比例微分的公式来进行计算,那在这样的力的影响之下,那整个系统如果说我要计算这个按它的运动,那我们其实可以通过仿真来实现。
那这个仿真啊,我们其实可以通过离散化,然后用欧拉积分来实现这个仿真的计算啊,比如说我们这里用一个半隐式欧拉,那扮演社拉的特点是什么呢,就是说这个速度更新啊,是根据力和当前时,就是这个力是用当前时刻算的。
当前时刻状态算的力,然后用这个来更新我的速度,然后呢用更新之后的速度啊去更新我的位置啊,这是一个这个扮演收拉或者是新欧拉啊,silesileo欧拉的这样的一个一个积分公式。
那当然这里其实我们这个首先做再说,稍微做做一下简化,因为这里力除以质量才是加速度嘛,我们可以再简化一点,我们认为质量就是一啊,那其实就可以把这个公式稍微写的简单一点,那当然不等于一,其实无所谓的。
这个其实同样的讨论,那当然这个地方因为f是一个pd control,是一个pd控制,然后按照我们一开始的假设啊,就是这里的力,都是根据当前时刻的状态去计算的。
也就是说这里的pd controls算出来的这个力啊,他应该是用x n,它就是当前时刻的这个位置,和当前时刻的速度来进行计算,ok所以说实际上我们可以得到这样一个公式。
那这里其实就是v和x其实都是我们的要求的,这个状态量,那当然这个公式我们可以稍微整理一下,整理成一个矩阵的形式啊,其实这两个是一样的,我就只是做一下一项,做一下代换啊。
然后最后变成一个变成一个矩阵的形式啊,首先就是因为这里边啊,是是跟x n和vn相关的,所以这里面其实没有其他多余的线,我们就是简单的就可以写成一个啊,如果说把vn和x n写成一个向量的话。
那其实它本质上就是一个矩阵乘以上一阵啊,上瘾,就当前时刻的v n和x n乘上一个线性矩阵,然后它等于下一时刻的v n x n,而且其实对这个简单的这个问题来说,实际上这个矩阵还是常数项啊。
它不会随着时间变化,那这里其实h我一直没说啊,就是h实际是我们这个啊时间不长啊,就是回想一下我们当时讲这个积分的时候,我们知道我们是把这个时间给离散化,那我们一种非常简单的方式,就把它均匀的离散化。
那个均匀离散化的过程中,相邻两个时间点之间的这个长度距离,那就是我们的时间不长,那这个其实是我们在仿真中,是一个非常重要的一个量,那如果说我们知道上一帧和下一帧,就是下一个时刻,和尚和当前时刻的关系啊。
是一个a矩阵乘上去啊,得到这样的关系,那如果这个其实我们可以进一步的展开,因为sn加一等于a乘以sn,那sn又等于a乘以sn减一啊,也就是sn等于a的平方乘以sn减一,然后我们继续不断迭代。
那么最终迭代,如果说s一是我整个系统的初始状态的话,那sn加一就等于a的n次方啊,a是一个矩阵啊,矩阵呢这a的n次方乘以s一啊,得到这么一个这么一个,有时候说从s11 固定的s一开始。
我觉得可以用这样一个通项公式啊,去直接计算出每一个状态下,我的sn的这个这个这个状态这个值,那当然这里其实我们可以进一步的做一些假设,就因为这个a实际上是一个22的矩阵吧,就是它是一个方,是一个方阵。
然后呢,我们实际上就是其实a的性质,很多时候是相对来说好一点,是比较好的,我们其实可以比较安全的,假设a是有两个啊特征值的啊,当然它没有的话,那可能这个这个讨论会更加复杂一点,可能我们需要去考虑。
就说当标准型那一类的这个跟这个代数的知识,当然这个实际结论上不会有太大的区别,就是从简单起见,我们只是假设一个简单的情况,a是有两个特征值的啊,同时有两个特征向量,那特征值和向量向量是什么意思。
我们知道特征值啊,就是特征向量a乘以v一啊,等于lada乘以v一啊,就是说在特征值和特征向量的意思,代表了在a作用,在特征值和特征向量上,它不会改变特征向量的方向啊,只会改变特征向量的长度。
这个长度的缩放大小,是由la就是特征值来给出的,那这是特征,这是那个矩阵的特征值的这样一个概念,那当然在这种情况下呢,其实如果说我们把v一和v2 ,它是两个向量,两个向量。
而且实际上我们其实可以很容易地搞,就是这个证明这两个东西是不共线的啊,我们可以把它写成一个矩阵p o,然后呢,其实a按照我们其实回想一下代数的知识,那他其实可以跟这个一个对角阵进行是相似的。
那其实是也就是a可以写成一个p,乘以一个对角阵,然后乘以p的逆的这样一个形式,ok然后这个p啊v1 v2 是一个固定的,因为a是一个已知的量嘛,所以v1 v2 是固定的,那这种情况下。
我们前面写到这sn加一啊,sn a等于a乘以sn,然后把这个格式行方式带进去,那就可以得s n加一等于p乘,以一个对角阵乘以p的逆乘,以sn好形成这样一个公式,那在这种情况下呢,我们可以做一个代换。
我们让z等于p的逆乘,以s也就是z n等于p的逆乘,以啊sn或者z n加一等于p逆乘,以s n s n加一,以此类推,因为这个p是固定的嘛,所以说时间这个代换是可以是可以可以,我们可以确定的把它写出来。
那在这个代换之下,那前面这个这样一个公式,我们可以直接带得到这样一个公式,比如说一个z它它的变化,首先可以发现就是它是完全是一个对角站,乘以z n的这样一个形式啊,我们其实也知道。
对角阵其实就是因为这是一个2x2,一个二乘以一个向量,所以实际上相当于是把第一个,它的第一个component就第一个数乘以lv 1,然后第二个数乘以ln 2,然后时间就完成了这样的一个计算。
那如果说回到前面,如果说我们想用通项公式,我们知道z n加一,如果z一的话是初始状态,其实这个在如果s一是知道的情况下,那z一我们是可以很容易计算的,因为本质上就是p的逆乘,以s一啊。
就得到了这个z1 ,那z n加一实际上就是a矩阵的啊,这现在变成了一个只是简单的一个lambda,就是一个对角阵,然后这个矩阵的n次方乘以z1 ,那其实这个矩阵的n次方,因为对角阵嘛。
所以它其实本质上是里边两个对角线上,也就是2a的两个特征值的n次方,构成一个对角阵,然后乘以z1 ,那这里其实我们可以可以得到一些性质,实际上如果说啊,因为这个首先a矩阵的两个特征值。
首先它不一定是实数啊,他可能是个负数,然后但是负数呢我们是有知道它是负数,有长度的,就是它不管它是实数还是负数,我们总是可以计算一个它的长度,对于负数来说长度,那就是实部的平方加上虚部的平方啊。
得到这么一个东西,那这里其实可以发现一件事情,就是当这个任意一个我这只是简单举例起来,兰姆达一,但实际上可以是朗姆达一或者栏杆二,任意中的任意一个如果它大于一的话,它的长度大于一的话。
我们可以发现是什么事情呢,就是说因为这个东西大于一,所以因而然后这个landa的n次方,它的长度,他这个lana一的长度的n次方啊,就一个数的平n次方是一个负数的,这个长度的n次方。
等于这个负数的n次方的长度啊,有这样的一个关系,所以说你就可以知道,如果说朗姆达大于一的话,那我们知道当n去,因为我们从零开始嘛,我不断的向后仿真,这n是不断增大的,所以让n就像无穷大,就增长的时候。
我们发现这个z n的长度也会变成无穷大,那自然是什么,z n是我们前面做了一个代换吧,z n本质上是p乘以s一啊,p乘以s,sp乘以s,所以实际上如果z的长度增大,那其实等价于我们也知道s相。
等价是s的长度也在增大,就这意味着什么呢,就是如果说有一个任何一个特征值,那它它的长度大于一的话,会导致我在仿真过程中,我的速度,我的这个位置啊,因为在本质上是这个速度和位置的一个线性,线性线性组合。
那这个东西会变得越来越大,越来越远离我的这个中心,越来越远,这个其实代表什么,代表这个系统就不稳定,实际上我们看到的时候,就相当于这个这个这个这个物体,在这里左右震动,左右震动,越震动越大,越震动。
最后飞的飞到无穷远去了,那就这是一个非常不稳定的一个反制系统,所以实际上为了能够保证仿真系统稳定的话,我们是需要一个什么情况呢,我们是需要保证所有的这个lad,就是a的所有特征值的长度都要小于等于一啊。
其实最理想应该是小于一,因为等于一其实也不是非常稳定的,那这种情况下,我们可以比如说我们给出一个值,比如说我当kp啊,kp等于五五百,然后kd等于20,这个时候我们把h它是时间不长。
我们把h作为一个变量啊,作为横坐标,然后纵坐标是什么呢,纵坐标是这个a的这个啊特征值的长度,的最大值啊,是这么一个东西,然后你可以看到这条蓝色的曲线,这条蓝色的曲线就是kp等于500k的20。
然后我的步长从一个很小的值逐渐变大,这个过程中它的特征值的大小的变化,那你可以看到这个,因为我们要求如果说我们这个系统是稳定的,那这个特征值的长度,最大的长度是不能大于一的。
大家可以看到将这个它们是小于,越来越小的时候,它其实是接近于,但是远小于的这个这个看起来好像大于,但实际上是小于一的,就是只是比较接近一而已,然后这一段可以看到大概在零点啊,0。040。0005左右吧。
大概这么一个位置,它它就已经到了一了,然后再增大它就会很快的很快的超过超过一,而且这个是单调上升的,不会再下去了,也就意味着什么呢,也就意味着,如果说我的h在我kp和kd给出这样一个范围,知识情况之下。
我这个h这个时间不长的取值不能小于啊,不能不能大于,不能大于这么一个零点点五,0。05左右的这么一个时间不长,00:00:05左右的这样时间不长,而你会发现,如果说我把这个kp增大,我把kp增大。
你会发现这个一一的这个点会更要求,会更加小一点啊,比如说kp等于500的时候,他是0。05kb等于5000的时候,那就必须是0。02左右啊,以下才能保持它的稳定,然后如果说类似的,如果说把kd调大。
那其实也可以看到这个要求,这个零点会更加偏右,也就是说实际上kb和kd这两个值特别是kp啊,就是虽然说我们知道kb调大的时候,我们会让这个系统这个误差更小,但是相对来说呢。
一方面它会让我的动作更更加僵硬,另一方面他会要求我使用一个更加小的一个,时间不长来进行仿真,但这是一个非常简单的例子,这是一个只是一个简单的木块,然后质量是一,然后只有这一个只有一个单单个变量。
但如果说对于一个更加复杂了,比如说人我们的人体啊,人体我们知道它有,首先这是一个旋转,是一个非线性的一个一个东西啊,然后另外一方面呢人呢其实关节很多,自由度也很高,然后在这种情况下。
如果说我们用pd control去控制整个这个角色的话,那我会面临一些问题,首先第一个问题就是说,我们知道pd control里面两个参数啊,kp和kd这两个参数呢,其实很大程度上会影响我这个角色。
他运动起来这个感觉这个状态啊,回想一下我们上节课讲的那个例子,就是kb大的时候他会很僵硬啊,但是kb小的时候呢,他又跟踪不上,就感觉非常无力,所以这个时候我们该怎么去设置这个kp和kd。
其实是一个比较考验经验的一个,一个这么一个过程,就是实际上这个没有什么特别好的办法,基本来说就是靠手调啊,就是我们调到一个感觉比较舒服的一个状态,就是一就可以一直用它,当然这个其实范围它调整的范围。
通常来讲你差一个,只要不差一个数量级,其实不会有非常大的偏差啊,就比如我们常用的一种方式,就是说kp是200啊,就因为它是计算关节力矩,就相当于每个关节对任何每个关节来说,它的kp是200。
然后kd是20,但这是其中一个可可行的一种方案,当然如果说你角色比较重的话,那你相信k b k的也要调大一点,当然这只是一个一种方案了,实际上这个范围也可以更大一点,其实我们常见的。
比如说我要做一个更加快一点的动作,比如说我要跳高啊,或者我要做一个后空翻,那其实可能这样的200,可能会你会发现他跳不起来,因为这个力量不够,所以你可能需要调大一点,另外呢就是说一些比较新的一些关节。
一些一些肢体啊,比如说这个脚趾或者说手,其实相对来说手其实很轻的,手手手只有几百克重,所以通常来讲,比如说我这个腕关节啊,我可能会kpu调小一点,所以这个其实只是一些经验之谈,就只说我们手工调整一下。
然后调整一个大家觉得满意的这样一个范围,但另外一个其实非常正需要这个强调的东西呢,就是说pd gas就是pd的参数,p k b和kd都是会容易造成我的仿真的不稳定,就像我们刚才这个举的这个例子。
那个那个木块那个例子,当然对于木块来说,我们发现好像也不会差很多嘛,0。01和100Hz每秒也可以啊,但是对于人来说,比如说这样一个角色,一个50kg的一个人,然后如果把k b k b设了200和20。
你会发现呢,这个很有可能你这个角色在100啊,在我这个反正牧场是准备1%秒的时候,他会非常不稳定,甚至你调到1‰秒都可能不稳定,就是我们我们很久以前大家用的时候,可能就是你看到以前很多的工作。
说我的仿真步长多少,还有仿真步长是1/1000秒,或者1/2000秒,也就是0。5或者1ms,这样一个量级,才能保持在这样一控制下的稳定性,然后如果说我把这个k pk调得更大的话。
那你可能会发现这个要求的不长会更加小一点,那不长想会带来什么问题呢,因为我每计算以每一步我都是要做一次,这个嗯那个运行啊,运动方程的一个求解,所以说每一个时间步,我都需要以相当一个相对来说比较。
固定的一个计算量,就这些算量基本来说,可能是跟我的这个时间的不长是不是很相关的,也就意味着什么呢,也就意味着如果说步长很小的话,我仿真一秒钟,那就需要更多的时间,不然后因为每一个时间步。
所花的时间是差不多的,那所以说如果说不长小的话,那我仿真一秒钟所需要的计算的时间就要更长,所以这其实是很大的一个问题,就是说因为我们知道在一些实时的应用里边,比如说游戏,我们这里边这个时间。
每一个我们需要保证这个连续性嘛,通常讲至少有60f p s吧,那就在这个1/60秒的过程中,我们需要跑仿真,需要考考我们的这个渲染啊,这要渲染是一个非常慢的一个过程,然后还有需要做一些这个逻辑计算啊。
这个特别是一些比较老的游戏,比如单用gpu来算,那其实如果这个里面东西很多的话,你会算的非常慢,那这个时候,如果说我们仿真本身还要占一大块空间的话,那其实这个其实对于这个实时应用来说。
也不是非常非常有意思,当然看你做什么了,比如说我们是做一个机器人控制设计,那这种时候,其实我们仿真步长确实应该放小一点,这样的话其实也是一方面,也是让我们这个计算更精确啊,那另外一方面。
他其实也没有这个这个这个实质性要求,但相对来说也好做一点,但不管怎么样,实际上对于我们一般普通的这样一个,kpd control来说,这个时间不长啊,通常来讲是不能放的太大的,你放稍微放大一点。
你就可以就会崩,就会这个系统就会崩溃,但这个大家可以,我们在下一个实验里边,会会会有这样的相关的练习,大家可以尝试一下,那如何能解决这个问题呢,那当然时间这个也是一个怎么说呢,就是就是需要一些改动。
对对仿真器做一些改动的一些技巧,就说是我们前面提到了我们这个半引收了啊,半也收了,我们是通过这样的计算啊,用当前时刻的状态啊,当前当前时刻状态来计算力啊,然后用这个计算出来力来更新速度。
然后然后再做后面的更新,那这里其实有一个什么问题呢,就是我们前面讲仿真的时候,知道一显示欧拉和斑也是欧拉,都是可能会不稳定的,就数值上可能是不稳定的,但是呢也是欧拉是稳定的,什么是野兽拉呢。
与肉拉就是表示我在计算这个力的时候,不是用当前时刻的状态去计算,而是用下一个时刻的状态去计算,然后下一个时刻因为他是不知道的,所以本质上来说它会变成一个方程,那我们需要解这个方程去获得下一时刻的状态。
那就代表什么呢,因为这里x n应该换成x n加一,就下一时刻的位置,然后v也应该换成vn加一,但是这里有一个问题在于x n加一,因为我们如果还回想一下,我们当时讲这个旋转的积分啊。
旋转我们如何从一个角速度变到旋转,变到这个cut in,首先这一步的计算,通常来讲是一个非线性的一个计算,那这个非线性会带来我们在求解的时候,会带来一些麻烦,就是会让我们的求解速度变慢,然后另一方面。
我们不能通过简单的这种这种矩阵,矩阵矩阵求逆一样就可以得到了,就冲来讲,我们还需要解一个非线性的,它会把这个方程变成一个非线性的方程,所以说会让我们求解变得非常复杂,所以呢其实有另外一种。
稍微啊比原始的这个这个pd要稍微好一点的,方法呢,就说我们是只是把这个pd control里边的一部分,变成影视的,也就是说这里边xn就是位置的部分,因为它很很经常它是一个非线性的,那就它不好算。
但是速度项啊,大部分情况下来说,速度像是一个线性的关系,因为主要是为什么,因为速度是导数,我们一旦求了导数的话,就很多东西这个非线性的就会变成线性的东西,那这种情况下呢,我们只是对速度。
就是还是比原来这个这个pd control里比,在原来是pd control,我们是速度是当前时的速度,然后我们改进一下,把这个速度换成下一时刻的速度,那这种情况下呢,我们其实刚才的这个啊。
我们这个这个迭代公式,或者我们这个系统方程就从原来稍微简单些,稍微变得复杂了一点,但这个其实也很容易解决,因为本质上vn加一是在这一行的,你可以很容易把它挪过来,然后除掉啊,就变成了这样的一个公式。
那这个公式实际上我们可以应用,我们前面刚才的那个那个技巧,我们还是可以画一个图,那这个图里边我们可以看到这个蓝色的,就是普通的pd control,原始的pd control啊,然后他的那个时间啊。
就是这个特征值的长度,跟这个时间不长的这样一个曲线,我们可以知道大概是在这个地方啊,它超过了一,那他就会就会失败啊,就不能所说的步长是必须小于0。01的,然后呢这个啊是我的这个新的这个控制啊。
就是我就是我pc control,是用下一时刻的这个vn计算,你可以发现他所需要的这个时间不长啊,最大的时间不长,可以相当大比接近于一这样的一个范围,就这两个大概可以差几十倍。
所以这其实这么一个简单的技巧,其实可以很大大大的加强啊,我们这个控制过程中,我们这个仿真的稳定性,就是本质上它还是个pd控制,但是只是说我们在这个仿真上加了一个,这个实现上加了一点trick啊。
来实现这个效果,那当然这个效果就是说我们通常来讲,我们在仿真器里边,就是因为这一步啊,其实相当于我去干预了这个仿真器或者,物理引擎的内部的这个运算,所以说实际上这个通常来讲,我们是需要自己去实现一下。
就它可能这个仿真物理引擎本身,可能不一定提供这样的功能,但是实际上呢就是当我们这个,这不就是稍微提一句啊,就是实际上另外一个方向的话,你是可以通过仿真器的一些啊,具体实现啊。
可以可能用一部分纺织机的功能,比如说我们可以采用什么呢,可以采用所谓的这个motor啊,velocity motor就是速度控制器来实现类似的效果,那这个就不是我们我们这里就不多,不多计较细节了。
但是总体来说大家了解是这样的,一个通过把这个速度变成这个隐隐式表达,就是下一个速度进行表达,可以很可以,很大程度上提高我们这个pd控制稳定性。
那当然这个其实也是一个他在这个节动画里边,我们经常会把它叫做stable pd control啊。
但这其实最早是这个啊,这个这这个这篇工作提出了一个方法,但本质上来说实验就是我们刚才提到。
他只是把这个这个稳定性最关键的一部分,其实后面这部分啊。
就是说我们用下一时刻的速度来计算,那这个其实就是个例子了,如果说没有这个bgan。
没有刚才我们这的这个情况的话,如果说有pd啊,kp比较大。
kb比较大,你可以看到这个仿真就很不稳定,这个转着转就飞掉。
但如果说用用这个stable pd,也就是说我们就加上这个in polish的单品啊。
就是加上这个啊v n加一的计算k p,那这个仿真会相对来说稳定很多啊。
特别是在这个步长比较大的时候,其实可以看到我们其实在这种情况下。
你可以用1/60的补偿啊,1/60秒,如果说不用的话,那你同样要更小一点,比如说这个简单的两个两个这个关节的物体啊,这样一个角色你可能需要一个,比如说可能1/600是稳定的,那这个需要实际去测试一下。
ok所以这是stable d,所以回到我们前面这个这个嗯我们这个例子,我们这个结论啊,就说通常来讲,如果说我们用显示的pd的话,那么可能需要很大的一个很小的一个部长啊。
就比如说可能2000 1/1000秒,1ms或者0。5ms,这样的时间不长,但如果说我们用step pd的话,相对来说会小一点,就比如说我们现在看到很多工作啊,他说诶。
我们我现在其实可以仿真在在120Hz,同时,那意味着其实我们是使用了这种stoppd的,这样的这样的做法。
ok那回答我们之前讲的,就是说我们只是简单的用pd去跟踪一个。
比如说我们把动捕数据啊,作为我们pd控制器的这个目标的轨迹啊,我们直接去跟踪,那通常来讲它是不work啊。
这个结果肯定是不对的,为什么呢,其实我们刚才也提到了,就是pd控制有两个问题。
一个是那个不好意思。
一个是就是啊这个稳态误差啊。
另外一个就是相位延迟,其实随时时间本质上来说,因为这个一下位的延迟,会导致我们比如说正常讲我往前走路,我需要身体和脚配合起来才不会摔倒。
但是一旦我这个身体和脚之间有个有个延迟,那我就这个平衡就很容易失就失掉了。
所以说就很容易就无法跟踪的很准确。
所以说我们之前讲a为了能够让它跟踪的准确,那我们在根节点上加一个力,但是这个力很大的一个问题在于什么呢,就是说我们关节的例句,我们上一个提到我们怎么加在这个角色身上的。
我们通常来讲我们是会在他的这个其中一个啊,肢体啊,一个body上加上一个力啊例句,然后在另外一个body上加上一个反向的例句,那这样两个例句,他其实是保持一个总合力为零的,这样一个状态啊。
就是说我们没有一个外来的一个一个一个力,来对它做功,但是这个根关节的这个例句,它是只是在一个关节,一个就是它根节点上,就跟的这个包上加了一个力,然后这个力是没有实例对象的。
就前面我们为什么要在另外一个body上加一个,反向的例句,是因为我们等价于认为这个例句是这个body,这个肢体啊,这个骨骼应到另外一个骨上了,那当然另外一个骨骼,要对这个骨骼有一个反作用力。
那这个根节点这里是没有反作用力的啊,所以说这个根节点它就是一个境外力啊。
就是它有一个非零的一个外力,那这个外力会带来一些特殊的效果,就是像比如说提线木偶一样啊,就是说相当于一个人撑着这个这个人的腰带啊。
趁着这个腰带,然后让它不会摔倒,但是整个动作看起来奇奇怪怪的,因为主要是因为,因为你因为大家习惯一个,这个正常真实世界中的人,他是不会有人揪着你的腰带往前走啊,就是这个这个看起来很不自然,很不自然。
所以说时间阶段的问题,就是说我们该如何去找到这么一个控制轨迹,那这个控制轨迹,我们不需要去根据点去来帮助我们。
那我们知道直接用,直接用这个动捕数据是不行的,我们刚才也提到了动捕数据,它直接就直接跟踪,会有这个跟踪不上的问题。
那我们该怎么去找到这么一个轨迹,让我能够跟踪上,就这个轨迹其实本质上来说是什么呢,就是说我们前面提到了。
为了让一个角色的这个胳膊啊能够伸平。
我们的目标状态,如果是正好是升平的状态的话,那我这个pd control是肯定不能让这个胳膊伸平的。
因为他总是要有一个偏差,所以为了能让能够让各位伸平,我需要把我的目标位置稍微设置的。
比这个伸平靠上一点,那这样的话这个误差会让我这个胳膊能够,能够保持平衡,所以实际上我们这个做轨迹的设计的时候。
其实也是同样的目标,就是说我们知道我要让这个角色,比如说看这个蓝色小人一样啊。
去做就去做滚动,或者去这个走路,或者坐到这个后后滚翻,那我们实际上是不能直接去跟踪,这个蓝色小人动作的。
或者就在这个记录这个之上去找一个轨迹,去跟踪那个轨迹才能去生成啊。
通过仿真来生成这个蓝色小人的动作。
那这个过程时间就有很多种不同的方法了,我们前面也提到了,之前有个公司啊,natural motion啊,他们做了一个软件,可以自动手工去设计这样的一个轨迹,当然这个手工设计是一种方式,但是会非常困难。
但实际上我们这个我们通常来讲,还是希望能算机做些事情吧,我们就希望能够让他自己去找到这样一套轨迹,那其中一种方法,比如所谓的轨迹优化啊,但是有时候我们也会叫其他的名字。
比如叫space time constraints啊,或者space time optimization,叫时空优化,但其实本质上做的都是一样的事情,就是就是轨迹优化。
那有一句话我们可以这个比较通用的描述一下,就是说比如说我们目标是找到什么呢,我目标是优化一个仿真的轨迹啊,其实我们知道我们把时间离散化之后,那它其实就是每一个时间角色的状态,包括角色的位置,角色速度。
角色的朝向,角色的角速等等这些状态,然后呢同时我也去优化一个控制轨迹,那这个控制轨迹可以是我的target rejection,我的目标轨迹啊,有有目标轨之后呢,那我们就可以用pd控制。
来计算每一时刻的关节力矩,然后把这个关节力矩施加在这个角色之上,它会动起来,那在这个过程中呢,我们需要去让我们这个啊优化嘛,我们需要去去优化一个目标函数,那这个目标函数呢。
我们可以这个泛化的写诗写成这样一个形式啊,它包括哪两部分,一部分是我这个轨迹结束的时候,那个状态,根据这当时那个状态算的一个目标函数,然后以及根据每一时刻我加了多少力,和我加了多少。
这个这个当前的状态来算的一个标函数,然后同时呢,我们还需要在优化过程中满足一些约束,这个约束是什么呢,首先就是主要是我们的这个运动学方程的约束,因为我们知道这个仿真的或者这个角色运动。
它的状态时间是因为是根据当前的状态加上我,比如说我当时给这个角色加例句加利,它会根据这个力通过仿真得到下一步的状态,所以说这两个状态和这个力之间,其实是有一个非常固定的关系的。
那这个关系就是我的这个equation motion,就是运动系统的运动方程,那在这种情况,其实可能还有一些其他的这个约束,比如说关节约束啊,比如说一些其他的,比如说可能要求这个角色不能走到。
比如说这个这个悬崖的边上,不然你会掉下去,那当然这其实也是一个对位置的一个约束,那把所有这些放在一起,那就变成一个优化问题,那我们就通过求解这个优化问题,来得到我们所需要的这个运动轨迹。
那当然这个其实右边,这是一个比较老的一个工作了,也是这个方向的一个就是比较早的一个,属于这个就是属于奠基性的一个工作了啊,就是一些188年的这个,这个这个也是发在西瓜上的,那他做的事情就是一个。
这是那个pika皮克斯的那个那个灯泡啊,他其实目标是说哎我想我想优化一个这个灯泡,跳起来到这里,这个动作,那这里其实你的这个状态其实就是一个灯泡,每个关节的位置和每个关节的这个朝向啊,角度啊。
和这个基座的位置,然后以及它们的速度,然后呢其实我还有一些力,这个力是我这里没有画出来,我就直接是需要加在这个每个关节上的,然后能够动起来,然后通过不断的优化这些位置和这个我施加力。
最终让它生生成这样的一个动画,当然我们可以有一个再具体一点的例子,其实还是上节课我们用到这个非常简单的一个,一个杆上穿着一个物体,然后我可以在这个物体上加一个力,然后这个路由体能够抵抗重力。
然后并且在这个目标目标高度这里,随着目标高度起移动,那如果说我们也知道这个f是一个pd控制的话,那我们这pd控制在有目标位置,减掉当前的位置啊,乘以k p,然后速度乘以kd。
然后这接下来的目标就是什么呢,我想去计算一个目标轨迹啊,一个这个这个pd控制的这个目标轨迹,使得我这个在这个控制下,我的仿真结果,这个s和x和t是一个sin函数,比如说这个。
我想让我想让我的仿真结果是这个sin函数,那这个x,我的目标轨迹应该是一个什么样的东西,那这个其实就是刚才我们说的,我们可以把它写成一个非常直观的一个,优化问题,那这个优化问题里边。
首先我的目标函数是什么,我目标函数是说x n,因为我需要xn的这个轨迹,是一个是一个sin函数,那所以我其实就相当于这个三三角函数,在t n时刻的值,应该跟xn在这个时刻的值是相同的,那这个相同。
我们可以写成一个这个啊,最小二乘的这么一个啊,这这个这个平方的差的平方这样一个形式,那同时呢我们知道这里边x n和v n啊,它是要满足我们的这个运动方程的,对这个例子来说,运动方程非常简单。
其实就是我们的简单,这个啊,这个也半隐身半隐式积分的这样一个过程啊,其实就是我们的运动方程,因为力的平时我们是知道的,所以它其实是这样的一个东西,ok那通常来讲呢,我们其实除了这个两个运动方式之外呢。
我们可能还会加一些额外的约束啊,就比如说我们希望如果说没有约束的话,那其实可能这个s它会变得非常大,或者说就是有些时候,可能我们这个系统约束不够的情况下,那可能s可能有很大的自由。
他可以选择一些大的电池或者小a的值,那我们可以加额外的加一些这种这种约束量啊,比如说这个正则项,比如说我要求我这ax必须是比较接近于零的,这样的话可以让我整个的这个输出的,这个轨迹会比较平滑。
会比较这个比较正常,ok那这种情况下,其实我们其实这是一个优化问题啊,它有两个约束,那这两个约束呢在这种情况下,如果说我们写成这样的形式的话,我们等会冲上来以后,我们会把它叫做硬约束啊,什么叫硬约束呢。
就是说这个约束是必须会满足的啊,因为它是放在下面这个约束相,我们不管用哪个求解器,它是一定会尽可能的满足这样一个约束,那应该是会带来一些什么问题呢,就是它可能会让我这个问题变得比较难解。
另外封面的话可能这个问题变得不是很稳定,条件是会变差之类的问题,所以有些时候我们也会把这个硬约束呢,变成一个软约束啊,其实本质上是相当于在音乐书里边,我要求他们俩,这这个这个左边和右边必须是相等的。
但是呢在如果说若人是软约束的情况下呢,我说这两个东西尽可能相等,但是也就是说他们俩的差应该尽可能小,但是呢我允许一定程度上的不等于零啊,随时转移数,所以这两个形式其实可以互相转化的。
就是我这里w代表了我这个软约束的,这个软的程度,如果它很大的话,表示我要求这个这个x等于零,是尽可能要一定要满足,那就说明这个这个就要进行更加硬一些,那我们可以通过调节这样的这个软约束。
这个权重来平衡啊,我这个约束的满足程度,以及这个我的目标函数的这样一个程度,那通常来讲我们这样一个软约束呢,它这个方程啊,就这个优化问题求解起来更加简单一点,那另外还有一些其他的问题啊,相关的一些技巧。
就是说比如说我们这里优化了目标,这个优化目标实际上是以这个离散化的轨迹,上面每一个时刻啊,这个角色的状态,那比如说我们的仿真步长是比如说1‰秒,那我仿真一秒钟的长度,那我就需要1000个状态。
那这1000个状态,比如说每个状态两个参数,那就是那就是可能是啊这里是6000个参数,那这个那这个这个整个问题就是参数,这个参数量会非常大啊,其实也会给我们的这个优化带来很大的问题。
所以实际上还有一些其他的方法,比如说所谓的collocation methers啊,就是名字其实叫这个有点有点有点嗯,有点有点怪啊,但实际上这个想法是非常简单的,就是说我们这里有1000个参数吧。
这个6000个参数,这个这个优化的问题太难了太大了,那我们其实可以让认为可以做一些简化,比如我们知道我们认为这个x v和xn,它是满足某些预定义好的这个参数曲线的,就比如说我认为x n vn和sn 8。
就它的这个目标轨迹,他们都是来自于某一个啊三个啊,三个不同的相应的这个比如说cubic plan,我们三次样条曲线,或者来自于比如说一个一个一个多项式啊,多项式函数,那在这种情况下呢。
我们优化这6000个参数,我们可以把它简化为优化我这些曲线的参数,那通来讲这个曲线的参数,我们肯定是比我这个完整的参数要多很多啊,少少很多的,那这样的话,其实会让我的这个优化问题变得简单一点啊。
这是这个所谓的collocation methods啊,实际就是这样的一个近似,通过近似的方法来减少我的这个优化的变量啊,这是一种一种技巧,但不管哪一种方法,我们最终还是需要去优化这样一个函数。
那优化这个函数实际上就有很多方法可以用,比如常用的一类方法,就是所谓的这个gradient based approach,就是基于这个嗯梯度的理性的方法,比如说大家比较熟悉的这种梯度下降。
然后还有比如说牛顿法,或者你牛顿法,顿法里面最常用的那个l b f q s a l b f啊,sorry那个词我忘了,就这类方法其实都是挺常用的方法,而实际上对于我们这个简单的问题来说。
其实可以很我们可以看到它是什么呢,它是一个目标函数,是一个二次函数啊,是二次函数,然后约束是一个线性的等式约束,所以这个是非常简单的一个q币问题,就是二次规划问题,那这个问题其实是有有有唯一解的。
我们其实可以很容易就算出它的解,那其实如果说我们不知道它的解的话,我们其实也是可以通过我们前面提到的,比如说梯度下降,我们讲i k的时候已经讲过这个问题了,其实i k我们是可以把它给转化成一个。
优化问题,那这个优化问题,我们可以通过比如说这种qq加呃,这个迭代的这种下降方式,我们不管是用gradient descent还是用比如ccd啊,cd其实本身也是一个当然不是梯度了。
它其实还是一个迭代的一个下降方法,然后一些其他的比如说牛顿法,或者是这个这个尼牛尼罗法,你牛的法啊,像是l m法等等方方法我们都可以找到的解,就是这样一个简单的一个例子。
我们其实是可以比较容易的找到它的根的啊,找到它的一个解,而且这个解是唯一的,可以比较比较效果比较好,然后如果是更加复杂一点的,比如说一个人啊,比如说我想让这个人这个角色跑步,那回到我们前面的例子。
如果说我们直接跟踪一个目标轨迹的啊,动补轨迹的话,那动捕动作的话,那它是跑不起来的,所以说我们通常需要在这个动物鬼把这个洞补,作为英国的这个初始解,然后用优化的方式去找到一个合理的,这个控制轨迹。
控制轨迹能够让这个角色能够跑起来,那这个过程中呢这个目标函数啊,其实写起来也比较简单,其实就是说我当前的仿真的状态,跟我的这个目标的这个轨迹之间做一个偏,做一个差,那这个差我们可以用什么方式衡量呢。
啊好多种不同方法,比如说我们可以算一下,两个pose之间的角度的偏差,那这是一种方式,还有一种其他的方式呢,比如说我算一算关节的,每个关节的全局的绝对位置,那这个位置它之间有个偏差。
我可以用它来计算这两个姿势之间的,这个这个误差,那看到还有一些其他的,比如说我们可能需要考虑一些,比如说角的啊,比如说每个关节的速度啊,比如说这个这个角色至新的相对关系啊。
那其实都是可以做我们的这个轨迹,优化的目标的,但是呢对于一个人来说,对于这个全身的一个复杂的一个角色来说呢,当我们定义了这样的一个优化方程之后,我们会发现,因为这个首先这个角色我们优化目标。
最终是它的姿态啊,它的这个关节的旋转,关节的旋转,我们知道它就是一个非线性的东西,另外呢整个这个问题这个角色的自由度啊,他身上这个关键的数量,它的参数都是非常高的,所以说如果说我们把这个函数啊。
就是这个优化目标函数的这个曲线,其实这时候就应该高于一个高维曲面了,这样一个曲面如果说我们把它画出来的话,你会发现它是一个非常非常非线性的高度,非线性,并且这个其实是。
甚至于这个曲面本身都是在不停的震荡的,这样一个状态,它有无穷多的这个局部最优解,那这种情况下呢,我们会发现,首先我们想要去计算它的gradient,通常来讲。
这个gradient是这个它的这个质量是比较差的,因为它总是离哪个,它总是指向某一个局部最优解,但是这个局部自由也就特别多,所以你接下来说这grading指向的方向,很有可能是不太对的,另外一方面呢。
很多时候我们的仿真啊,我们先是一个黑盒子,黑盒子意味着什么呢,意味着我们前面那个公式里边,其实这里其实是我们整个系统的,它的这个这个这个系统系统函数啊,系统system dynamics。
这是一个问我们知道的,但是对于一般系统,比如说一个机器人,它怎么动,我们很多时候是无法准确的去建模的,就比如说我们前面提到了一个最基本的问题,碰撞我们该怎么建模啊,这个其实就是一个很难的问题了。
比如说一个一个球球掉在地上,他该弹多高,那这种情况下我们其实很难,就是这个碰撞模型,很多都是一个非常非常粗略的近似,然后另外一个比如说我这个是系人,他他比如说我手人的手,人的手是软的。
我用人的这个软这个手去捏一个笔,比如说我捏起了一支笔,那这个其实是非常容易,它这个软的会会带来非常非常稳定的,这样一个接触点,但如果说我们仿真的角色里边这个手是硬的,你可以想象我用这个硬的笔。
或者你可以想象我用筷子夹这个笔,它会非常难的,但是这个这种男的这种这种情况下,他又跟我真实的这个人,这个捏这个笔这个过程又是完全不一样了,其实很多时候我们是很难去准确的去建模,我们这个角色啊。
他的这个整个运动过程,但是没有建模的情况下呢,那我们其实也没法算它的这个梯度啊,它是gradient,因为模型我都不知道我该怎么算梯度,所以这其实也是这种gradient base。
就是我们基于梯度方法的局限性,因为它必须要一个梯度嘛,但是很多时候梯度是我没法算,其实很多时候我们在这个角色动画里面,就是当我们需要去做古籍化的时候,其实也不一定,不过不光是角色动画。
其实很多这种就是控制领域也都同样的问题,就我们需要去做古籍化的时候,我们就会碰到这样的一个非常差的这么一个啊,这么一个这个所谓的landscape,就是这个优化函数。
那我们这个gradient board的话呢,我们就是希望能找到一些这种不需要gradient,derivative frame,optimization methods啊,这我们不需要梯度的方法。
那不想提的方法,通常来讲是一些所谓的启发式的方法,或者是基于这个随机这个随机的方法,或者基于采样的方法,就他们是通过什么呢,他们是通过若干样本点的信息来去更新,我最最最价值的一个估计,当然好处是什么呢。
好处是不需要这个梯度,坏处是什么呢,坏处是这个因为不需要梯度,所以我很难,一方面很慢,我只能估计嘛,所以估计的过程就是就是比我直接用函数算,要慢的,另外一方也不是很精确啊,所以总是有些有些优缺点。
然后通常来讲我们这是简单的写的,就这一类的方法大概都是这样的一个流程,就是目标是什么,目标是我找到一个函数,一个变量x,它能够让我的某一个目标函数最小化,那在这个过程中呢。
首先我需要用某种方式去有一个初步的估计啊,但这个估计比如说对于我们这个跟踪来说,比如说想要一个角色就跟踪一个动捕数据,那其实动捕数据本身就可以作为这样一个初始,初始的这样一个估计。
那接下来是一个迭代过程,那这个迭代过程首先我从根据当前的这个估计,我去这个生成一些样本点,然后呢,再对每一个样本点上去计算我的一个目标函数,那我可以计算计算出来每个样本点上,这个函数的值。
然后呢我再根据每一个函数的值,哎我再去更新我的x的估计啊,当然这个只是一个框架,是这样子,但实际这个细节上不能方法会会区别比较大,那当然很多很多相关的方法了,比如说贝斯优化啊,比如说这个这个遗传算法啊。
就是这个这个这个叫叫进化算法,然后像比如说我们之前的这个,在机器里非常常用的这种随机梯度下降,其实本质上也是一类方法,有些其他的,比如说基于采样的方法等等,当然这里我们只介绍两种啊。
比较也算是效果比较好的方法,其中一种就是所谓的这个c m e s啊,这个这个covious mission expectation,evolutionary strategy,它其实还是一个进化算法啊。
就是他就是其实本质上还是我们刚才说的,就是我撒一些点,然后根据一些点来更新,我的这个我对最优最优质的估计,那当然对于c m e s来说,它其实是把这个撒点的过程啊,就是就是估计的过程,估计这个点啊。
所以所以有几日的过程,我把它转化成一个估计啊,一个高斯分布的这样一个过程啊,就是说我是假设,我是假设呢就说我的点,每次我需要采一些样样本点,然后然后根据这些样本点去更新我的这个估计,那这些样本点呢。
我是总是从一个高斯分布里边啊,这个就是高斯就是正态分布啊,一个高维的一个正态分布里边去踩这些点,所以说整个这个过程就是说,我首先初始化一个高斯分布,高斯分布可能就是一个圆形的一个分布。
然后接下来呢我比如说我踩100个点啊,撒100个点,然后我对每一个点去计算一下,我的目标函数的值,当然还是这里提到,就是说我们前面也提到目标函数是什么,目标函数是一个在每一个状态下。
它的这个函数的值是求和,所以时间本质上来说对这个函数进行求值,我其实相当于什么,相当于做了一个仿真啊,仿真生成了一个比如几秒钟的一个轨迹,然后在这个轨迹的这个上面,我算了一下我的这个函数值。
比如我根据我需要,它这个轨迹跟我的这个某个参考动作相近,或者比如说这个轨迹里边我要求比如踢球,我要你这个脚必须碰到球的上面,那可能有一个一个一个目标函数来做这件事情,那得到这些轨迹之后呢。
我可以算出每一个点,每一个参数,每一个x所对应的这个参数值,然后c m c m e s做的事情,就说我我对这个参数值做一个排序,有些这个参数这个这个app比较小,也是比较大的,那我其实知道这个比较是。
因为我目标是最小化这个f嘛,所以说我就是从最小往上找,我保留n个,但这n其实是一个可以算的一个参数,比如我才100个,那我可能从里边只从里面拿,比如说20个啊作为更新的这个点。
然后接下来呢我更新我这个高斯分布的mu啊,就平均值和西格玛就是我的这个方差,然后呢去然后接下来下一步的时候,我就从这个更新之后的这个高层布里面去采样,所以整点u c m s它的过程大概是这个样子啊。
就是说这个我开始是一个圆形的高斯,正一个初始化的高斯分布,然后你会发现有个有些点,它会非常相对来说比较小啊,力气比较短,比较大,它会逐渐的向比较小这个方形移动,而在移动的过程中。
开始的时候它的这个方差会逐渐增大,然后这个代表了,其实我在正在去向外去去探索更小的方向,然后呢,当然后当我这个方向逐渐集中了之后呢,这个方差异会逐渐变小,最后收敛到这个最优解附近啊。
这是cm e s这样一个特点,当然这种方法的好处是什么呢,就是首先它是一个比较稳定的方法,就是相对来说这个对一些很复杂的函数呢,这个实际效果也是蛮好的,另外方面就是确实它也是一个没有基啊。
dirty free,就是就是不是基于这个梯度的方法啊,所以说如果哪怕是非常复杂的这个系统啊,或者这个黑盒子系统,我们也可以直接把它应用起来,但是之前有一些工作。
比如说这是一个呃这是那个09年的一个工作,那这个其实他做的事情是什么呢,就是说我给出一些就是比如人走路嘛,你总是左右脚左脚着地,右脚着地,我可以给出一些预测的这个落地点的位置。
然后接下来呢我靠着轨迹优化啊,去找到能够满足每次落地点的这样的一个,走路的这样一个形态,所以首先这个效果还是蛮好的,就是说比如我开始就给左右左右左右,随便给一些这样的一个位置。
它可以根据这些位置生成一个走路,而实际上如果说我这给的位置的这个距离,还有这个这个速度有不同的话呢,其实他这走路的姿态也会不同,而且甚至yes,sorry,不好意思,而实际上如果说我们的这个角色的这个。
比如说这个关键的数量不一样,那它它不像真人一样,那这种方法上,其实也是能够找到一个比较合理的,这个走走路的这样的一个过程,那另外还有一些其他的工作,就比如说我们刚才那个方法实际上是做什么的。
他是同时去优化我的仿真的轨迹,以及我的控制变量,那实际上我们知道pd control,如果说我们只是把,就如果说我们认为这个嗯,就是这里边最这个需要去控制量。
其实就是我们的目标轨迹,当我们给中目标轨迹之后,剩下的部分其实是仿真,直接直接可以得到。
所以实际上另外一方另一另外一种方法,就是我们只去优化这个仿真轨迹,而不是去优化我的这个,这个只只去优化这个pd的这个目标轨迹,而不需要去优化我们的这个仿真轨迹,仿真轨迹我们可以直接通过仿真来实现。
所以这种方法其实也是可以得到一些控制的啊,就是比如这也是一个一些方法,我们可以做一通过一些非常简单的目标,比如说我就想让这个角色绞尽可能提高,然后是同时身体身体有一个旋转,那它就可能生成这样的一个。
比如这种这种街舞一样的动作,那这其实也是3m e加上我们的这个仿真控制,能够啊,加上我们这轨迹化能够实现的效果,那除此之外呢,还有一些其他的方法,就比如说c m c m e s做一个非常特点。
就是说每次我打一个这个给出一个样板参数,我们都需要做若干个这个从头到尾做一下仿真,然后呢再去更新这个参数,那这个整个过程其实是比较漫长的,而且另外一方面呢,其实如果说我们这个仿真的轨迹比较长。
实际上它会带来更多的啊,这个局部最优解,就是让我的仿真的目标函数变得更加,难难难收敛,所以之前还有一些其他的方法,比如说sam港啊,这其实我们在10年前这个提出的一类方法,他主要是说我们它主要就是说。
如果说我们有一个动捕数据啊,我们需要去找到这么一个目标轨迹,然后我们能够跟踪这个魔鬼目标轨迹,还原那个动捕数据,就是解决这样一个问题,其实本质上跟前面3m s,那个优化问题是相同的。
但是跟那个三vs不同点在于什么呢,就是说每次我们做采样,我们只考虑下一帧,就是我们每次只是优化一步,然后通过这一步来决定,我们后面该去怎么去更新我们的这个这个状态。
我们我们这个这个这个轨迹的拖着轨迹的值,当然这个其实本质上是一个sequence,圣母这个系列蒙特卡拉蒙特卡罗方法,就这个方法一个特点是什么呢,就是我可以从一些初始状态开始,我采一些若干个样本点。
然后向这个页面点击仿真,仿真完之后呢,我们其实像是像c m e s一样,我们可能只是从这一仿真之后的结构里面,拿出一小部分样板点作为新的出发点,然后再去采更多的样本,然后依次这样类推。
直到我们把整个这个踩完,但对于我们现在这个具体的例子来说,就比如说这是一个动捕数据啊,这是我们需要去跟踪的一个轨迹,也许是比如说这个动画师建的一段动作啊,也许是一些其他的一些控制。
然后这里我们有一个初始初始的一个状态,比如这个人往前走,那肯定他是从一个站着的状态开始,我们知道这个本来如果说我们直接用pd控制,去跟踪这个轨迹,那么他肯定是博尔啊,他肯定是会偏差比较大的。
然后呢为了能够跟踪的比较准确,我们实际上是需要在这个轨迹上去加一个偏离,然后跟踪一下那个加了偏移之后的轨迹,那么它就更应该就会有一部分,会跟这个轨迹比较接近了啊,这是一个基本这样一个优化目标。
但这个优化过程呢,就是说我们其实还是把这个轨迹给分割开啊,我每次只是优化一小段,然后在这个小段里边,我们要求是什么呢,就是说我们可以因为我们前面提到,我们是需要在这个轨迹之上加一个偏移。
然后跟踪这个偏移之后的轨迹啊,来来产生这个优化这个仿真轨迹,那这个我们可以这个偏移,因为我们不知道嘛,所以说我们可以在一个根据一个高斯分布,去对这个偏移进行采样啊,当然这个不一定是高斯本布隆。
其实也可以用一些其他的,比如说这种这种这种这个均匀分布,其实也是可以的,在采样之后呢,其实我就采,比如说采1000个样本,那每个样本都对应了一个偏移啊,对这个原来这个动作,这样一个动轨迹的一个偏移。
然后接下来呢我对这个每一个偏移量,我都可以去做一次仿真,诶,不好意思,那一每对于每一个片段,让我反正之后的结果它会生成一个新的状态啊,那这个状态其实有一些呢,会跟我们的这个轨迹比较近。
另外一些呢可能跟我的轨迹比较远,那我们其实可以保留一些跟这个轨迹比较近的,那当然我们不会只保留一个,因为只保留一个会有什么问题呢,这一个可能是一个局部最优解,局部最优解可能会在后面的。
后面的这个仿真过程中,会变成一个非常差的一个一个解,所以说我们可以多保存一些,比如保存这个一,比如1000个,我们可能比如保存100个点,那作为你这100个点,会作为下一个阶段的起始状态。
那接下来呢其实我们还是产生若干个样本啊,比如也是1000个,然后这1000个里边都是就是会随机的,从这个我们上一次保留下来这个起始点出发啊,去做进一步的仿真,然后同样的这些仿真。
有一部分离这个轨迹比较近啊,有一部分比较远,我们这远的就是失败了,我们就不再留他了,然后我们只是留一下比较近的那一次,可以可以不断的这样进行下去,我们最终会找到一个一组轨迹,那这组轨迹里边有相当一部分。
会离这个这个目标轨迹比较近,那我们就可以把这里边最接近的那个找出来,那这个其实就是我们最终的这个解,但这个过程时间本质上是什么呢,本质上来说就是虽然说我们只考虑了一步啊,这可能是一个非常局部的一个问题。
就是非常local,非常容易陷入局部最优解,但是因为我们通过保留多个state,在多个这个状态,可以一定程度上让我们就每一个点,每一个局,每一个这个局部自由点,都会这个延迟到后面若干步之后。
再去判断这个绝对数学界是不是真的最优解啊,通过这种方式的话,其实也是说让我们这个每一步的判断,能够更加的这个这个不不局限于当前这个局部,其实也是让我们稍微这个啊优化过程,会更加的这个嗯更加的有效率一点。
那当然这就是一些这个这种方法的结果了。
其实也是就是说,首先我们可以很容易对任何一个动作,只要我们有他的这个动捕数据,那我们基本是肯定可以找到一个控制轨迹,能够还原这个动捕数据的。
那另外其实在这个过程中呢,我们其实可以做些什么事情呢,我们可以把这个环境做一些变化。
比如说这个比,或者把这个这个角色本身做一些变化,我们前面提到了什么问题,就是这个retargeting,当我们需要把一个动作去,把它重归向另外一个动作,觉得这样的时候,我们会不可避免出现什么呢。
比如说穿模,比如说这个角色跟d跟这个环境会有一些碰撞,会有一些接触,那这些问题的话,我们可以在这个优化的过程中呢,而且会产生一些,比如这地上有一些鹅卵石或者一个冰面。
那个角色就会自动的会受到这个环境的影响,而产生一些动作的变化啊。
这其实是整个这种方法可以得到的一些效果,那当然这种方法其实本质上是什么呢,就是我们最终得到的是一个啊face forward control啊,叫前馈控制,或者说叫开环控制,什么意思呢。
就是我们前面得到的其实就是一个控制轨迹,这个控制轨迹呢我们用pd control,用这个pd控制去跟踪这个轨迹,它会得到一个仿真轨迹,这是我的这个目标,但是这个过程中呢,我们必须要求这个跟踪过程里边。
我的起始状态,或者说仿真过程中的每一个状态,都是在我获取这个轨迹过程中能够得到的状态,你的意思是什么呢,比如说在一开始的时候,我对这个角色加了一些扰动,比如说我推了这个角色一把。
那如果说我们继续跟踪原来这个轨迹的话,你会发现这个角色他很快就会摔倒了,就会这个状态就会偏离很远,所以这是前馈控制的一个一个很大的问题,但为了能够解决这个问题呢,我们还是需要去引入所谓的反馈控制。
反应控制做的是什么呢,就是我们每一时刻会有一个反馈的一个,一个策略,这个策略它会自动的根据当前的状态,比如说我经过一些扰动之后,这个从s0 变成了s1 ,那它会根据s一跟s0 之间这个偏差。
这个片场它会自动计算出一个更新啊,就更正就在原来轨迹上加了一个更正,然后这个更正加到原来轨迹上之后,我再用pd control跟踪它,那这样的话,这个s机会越跑越远了,它其实会,我会希望他会回到这个。
原来我们目标的轨迹附近,但是它不会完全的精确地回到这个这个轨迹上,他总是会在附近,那这样的话,我们可以每一步都会有相应的这个反馈策略,来去加上去,那可以保证,虽然说我不跟跟原来标轨迹是不重合的。
但是我在整个访谈过程中,他都是跟这个目标轨迹啊,在这目标可以附近啊,不会离得很远啊,这是我反馈控制能够实现的一些效果,当然如果说我这个比如说一个跟踪控制之上,加上加上反馈了,那这个角色比如说可以推他啊。
他其实可以看到这个动作,他其实会受到相当的影响啊,但是最终这个啊角色还是可以保持平衡的,单质只是反馈控制的一个基本概念啊,那我们该怎么去实现这个反馈控制,我们今天这期只讲一个非常简单的一个例子。
就是所谓的这个静态平衡,我们知道这个pd control,嗯实际上节课我也举的这个例子,就是说比如说我让pd control的目标是一个pose,一个t pose,比如说那这种情况下。
其实这个peoples本身是没有任何平衡控制的,就是一个pose,那如果说我直接做这个,比如说他其实会比rog好一点,rag out是完全没有控制,这个人就瘫在一起了,但是在这种情况下呢。
比如说我就跟踪一个单一的姿势,跟这个单一的知识姿势呢,你会发现这个角色他虽然没有,他虽然能撑住自己保持这个姿势,但是它会逐渐的摔倒,对这是就是说我们其实是缺少了一个反馈控制。
能够在他将要摔倒的时候把它给更正回来,那我们继续下,那我目标是什么呢,就是说所谓的static balance,我们其实讲的是什么,就是在我不发生移动的情况下,就比如说我这个脚是原地站着。
站在那里的时候,我可以通行通过一些非常简单的这个控制策略,让这个角色呢,比如说让它左右稍微摇晃一晃,或者说在这个我可以推它一下,让它发生这些扰动,但它不会摔倒,甚至我可以让这个角色。
比如做一些什么原地下蹲啊,或者原地的这个这个晃晃肩啊,这种动作,然后能保证不摔倒啊,这其实是一个static控制,但这个其实是一个非常基础的控制,就是在这个之上,我们其实可以可以做一些很fancy的。
一些一些一些效果,那这里其实一个最基本要有问题,就说怎么什么是平衡,或者说什么是static平衡啊,其实我们可以想象一下,比如说这是一个立方体啊,不是这是一个一个圆柱体,一个是墩子,然后把它放在地上。
我们可以想象它非常稳定啊,怎么推它都是都都,就是我们只是一般就推一般的去推,他的话是推不倒的啊,甚至你把它稍微推起一点来,他也会在自重的作用下又回到这样一个状态,那我们其实可以站,为什么它要平衡呢。
其实可以看到它这个首先这个物体啊,它有一个质心啊重心,然后这个重心在地面上有个投影,ok然后呢整个这个圆柱体啊,它在地面上就是它底面是一个圆嘛,这个圆实际上我们可以把它叫support polygon。
就是支撑面,人们会发现这个角这个固体它的重心在地面上,投影,是在这个支撑面内部中心的,而实际上我们是可以知道可以比较容易的,这样有这样的一个感觉,就是说只要我的这个3d max,就是首先这个物体。
如果是一个基本一个一个准静状态啊,就是基本不动的一个状态,没有速度,在没有速度的情况下呢,我的set of max又在我的至亲子polygon,就是我的支撑面之内,那这个物体就是稳定的啊。
就哪怕他抬起一点,我也会把他拉回来,落在这个中间,那对于人来说其实也是类似的,比如说人,比如我人站在这里,那人其实也有智心,那中心那中心怎么算啊,其实我们一直没讲,但其实这个重心这个概念也是比较简单的。
因为这个每一个钢铁的重心,我们知道它是每一个小的这个质点的质量,乘以位置,然后然后然后再除以总质量啊,得到他这个缸体的直接对人来说也是一样的,我就相当于每一个缸体啊,每一个肢体它的重量。
它的质量乘以它的位置,然后再除以整个人的质量,就相当于就是我我对他的位置用啊,加上用质量来做一个加权平均,得到的位置就是重心,ok那这个人其实我的重心我站在那里的时候,实际上我的重心在地面上。
也是有这样的一个投影,然后在这个过程中,比如我两个角很平稳的站在地上,那这个两个角之间构成了一个立方体啊,平一个一个多面体,一个平面,那这个多面体啊,就是所谓的我的这个支撑平面啊,就比如两个脚站在地上。
它是非常稳定的,就是这两个角的脚面,然后呢连这个凸包啊,其实构成了一个支撑平面,然后当我保持平衡的时候呢,我只需要保证我这个3d max,我至今它的投影始终在这个支撑平面内部,那这个角色就不会摔。
他就没有处于这个正在摔倒状态,或者他就不会摔倒,所以说为了实现这样一个static balance,就是一个静态平衡,所谓静态平衡是什么呢,就是这个角色不动或者说动这个运动非常小。
就是速度很慢的时候得到这样一个静态平衡,那这个静态平衡我们该怎么实现呢,就是说首先我是需要跟踪一个静态的平衡的,这样的一个姿势啊,比如说确实就是这样一个姿势,这个人站在那里两个角。
两个角这个水平就是非常立立正一样啊,站在地面上,那这样的姿态本身它是一个,我们其实人感觉一下它应该是平衡的,它不是一个单腿,比如单腿站立的姿势,感觉就是不平衡的,那个就很难去实现这样一个静态平衡。
其实主要音也是因为单独站立的时候,你的这个support polygm就只有一只脚那么大,所以说你要想让你的重心始终在这个support,polygon的这个上面,相对来说会比两个角扎的时候要难很多。
就两个脚站立的时候,它是两个角中间的这个图包,他其实比一只脚大很多的,所以说你控制起来更加容易,比如首先我需要跟踪一个比较稳定的这样一个,自然站立的姿势,除此之外呢。
我还是希望去调整实时的调整我身体的控制好,使得我的这个质心在水平面的这个投影,始终是在这个sport polygon啊,就这个支撑平面的中间啊,这是我的目标啊,通过这种方式的话。
我们其实就可以保持平衡了,那这其实我们还是就是,在我不知道该怎么办的时候,其实最简单的方法就是拿一个pd控制,来来来干这件事情,就比如说我们可以用pd控制的方式,去计算一个反馈的例句。
就是说首先我们有一个例,就这个角色本身他需要保持这个姿势,我们已经有一个例句了,这就是pd控制去跟踪这个姿势得到力矩,然后在这个列举之上,我还在一些关节上加上额外的一个例句。
那这个例句的目标是去保证我的这个智心,始终是跟我的一个目标的执行位置比较接近,那当这个目标的执行位置,实际上我们通常来讲,可以把它认为就是这个ort polygon啊,就是这个支撑平面的中间。
或者说再简单一点,我其实就是两个角,两个角中心的连线的那个中间,那就是我的我的知心需要保持的位置啊,这可是也是一种近似,那pd控制就可以这么实现了,首先是一个目标目标位置啊,就是ort polygon。
就是支撑平面的中心,剪掉当前最新的这个投影位置,然后做一个比例系数,然后呢减掉我知心的速度啊,执行速度是什么,就是每一个关节啊,每个肢体,每个body它的速度用质量去加强平均啊,那这个东西得到了一个十。
我认为是一个例句,那这个例句该加在哪里呢,实际上来说啊,除了除了除了我们前期目标之外呢,我们其实还有两个重要的参数,就是kb和kd了,就是这个pd control的这个参数啊,当这两个参数呢。
我们其实通常来讲也只能通过首调的方式,就是或者就是这种方式,就是很多时候你需要多尝试几个手工,去尝试几个值就可以得到比较好的,因为这个相对来说这个控制还是比较简单的,那当然这个计算这个例句之后呢。
我们需要把它去加在一些关节上,那常用来说我们是可以把它夹在这个踝关节上,就夹在这个脚后跟上,是一种思路,或者也可以加在我的这个髋关节上,也是一种思路,其实大家可以想象一下,比如说你站在平面上。
我就是保持平衡,我稍微让自身身体向后倾斜一下,你会感受一下你到底是哪里来的,用力,基本来说是脚踝或者是这个hip,就是你的这个大腿根这个关节在用力,所以其实也是这样的思路。
就是你可能就是加一个就可以不用,不需要两个都讲,然后另外呢就是比如说我有两个hips,或者两个uncle,那时间那个套可以是两个,根据两个不算的,是可以采可以采用不同的参数啊,这也没有问题。
当然实际上这个区别可能不是很大,所以这是一种方式,就是通过这种方式的话,我们可以很简单的实现一个static balance,就是一个pd控制单柱子,这边还有一些其他的方法。
那这里我们其实稍微再多讲一个,多介绍一个控制策略,就是所谓的这个雅克比啊,这个这个转制这coin transpose很重要啊,感觉这个名字很熟悉啊,我们当时讲i k的时候,有一个方法。
就是就是就是就是jacoin transpose啊,还可实际上本质上,这两个东西是有非常大的联系的,就比如说我们这样有这样的例子,比如说这个人站在这里,然后我想我在这个手上加了一个力f。
ok然后呢就说我是当然这个app我没有真的加,我,就只是说这个,如果说如果说我要在这里加一个力的话,那这个力其实会让我这胳膊向上移动对吧,那这个向上移动我们可以等价的,等价的通过什么实现呢,等价的时候。
我这个向上移动这个过程,我可以反过来是通过我这个每个关节进行例举,加一个力矩,让它旋转,产生一个向上移动的这样的一个动作,o然后接下来的问题就是说,如果说我想让这些关键例句啊。
这个和我加一些合适的关键例句,它能够产生一个动作,那这个动作呢刚好跟我等价的,跟我在这个手手指上加一个力,产生动作相同,那这个是这个那这个这种计算啊,就这时候得到的这个套啊。
其实就是这个我们其实本质上是展开分差错,更重要就是这个jacky transports control的这个目标,其实就是计算这位这么一套,能够完成这个等价的这个这个力的效果,那当然这里特别要注意的。
就是说,我们是要用套用关键例句来等价的实现一个力,但这个力并没有真的加在这个物体这个肢体上,它只是说我们想要实现这么一个力的效果,所以这个力通常也叫water false,也就虚力啊。
就是他没有真的加上去,它就只是这个我们目标是要实现它的效果,那这个效果该怎么定义呢,我们通常来讲是说我们我们想要这个效果,我们可以通过做功来进行定义来进行衡量,也就是说我想让比如说我加了一个套。
加一些关键例句,我是希望这些关键例举所做的功啊,跟这个力这个虚拟的力他会做的功,他可能会做的功相同,或者再进一遍,其实我们其实更加考虑一个顺带的一个状态吧,所以实际上是要求是这两个力,一个是虚拟的力。
一个是真实的这个关节力矩,我要他们俩就这个真实的关键例举,他做的功的功率,跟这个我要目标要实现这个力的功率,应该是相同的,那这是我的这个计算目标,那功率是什么呢,功率其实是这个力乘以速度啊。
其实力点乘速度是一个转置乘以这个速度向量,这样一个形式,那这个这个地址来说,实际上是这个力矩的转置乘以这个角度的变化,得到功率,那接下来呢,其实这个因为我这个力是加在一个点上的。
那这个点它都有全局坐标的位置,我们知道它是有一个这个前向运动学的过程,也就是说它其实是x,是每个关节转角的一个函数,那这个函数是一个非线性函数啊,当然我们只是简单的写成一个gx,那有这样的环境函数之后。
那我自然知道x的导数,也就是说这个这个点的速度,应该是每个关节的旋转的速度啊,乘上一个雅克比矩阵得到的,那有这样的关系之后呢,其实把这个x等于j fa点啊,带入了上面这个公式。
那我们就可以得到这个这样的一个形式,就是f t乘以j z的点,等于tall乘以t乘以c点,当然这个公式我们是要求,对任意一个c点都是成立的,那其实就是要求什么呢。
要求这个套的转置等于f t f的转置乘以乘以,甲壳比小比真或者说两边都转置一下,那就是要求我的套,它必须等于这个亚比矩阵的转置乘以f,那这个其实就是japan transpose control。
它本质上做的事情,你的目标是什么呢,就是说我想让这些关键例举,它能够实现跟这个力加在x上得到同样的效果,那我就相当于我需要计算一个这个加力点,这个x啊,他的这个前线运动学函数的这个。
亚比矩阵的转置乘以得到这样一个关系,啊回去回忆一下,我们其实这个东西本质上来说就是ik问题,因为ik的时候,我们本质我们其实也做了同样的事情啊,我们其实就是需要对这个前向运动学这个。
这个函数去求导得到的雅克比矩阵,然后对,然后这个亚比阵其实本质上就是gradient嘛,我们可以根据gradient做各种事情啊,从梯度下降啊,或者机或者一些夹克变成pose的方法。
那这个雅克比矩阵其实有很多种,不同的计算方式啊,啊比如说如果说我们这个嗯,比如说对于hina hunt或者一个ball joht来说,我们其实是可以通过这种差成的方式来计算出,雅克比矩阵里的每一列。
这是回忆一下我们讲ik那一节讲的内容,当然实际上你可以发现这个就是j t乘以f啊,如果是我们top,其实就是如果说我们套,他就是我们把它分解到每一个旋转轴上的话,因为套本质上是一个在。
它是它是沿着某一个轴的旋转,我们其实可以认为是沿着三个不同的,旋转轴的一个叠加,但实际上我们可以从这个差成这个关系,我们其实可以做一些推导,那当然这个推导我这就不再仔细做了。
但是实际上我们可以推导出什么结论呢,就实际上对于亚克trans pose的情况来说,我们可以得到什么结,就是这个每一个关节它的关节力矩,实际上呢可以写,可以直接从这个点到这个关节之间的。
那个向量叉乘我这个app啊,得到我需要加的这个例句啊,其实我们是可以得到这样一个结论,那在这样的结论之下呢,那我们其实前面提到的这个static balance,就是静态平衡,我们前面提到。
ok我可以去算一个false,算一个例句啊,这个例句直接加到hp上,这是一种方式,但是这个只能做非常简单的这个平衡控制,但是说我们可以在这之上,在除此之外呢,我们可以我们可以换一种方式。
我们可以通过这个virtual false,这个蓄力的方式来实现类似的效果,就是什么呢,就是我还是用pd控制去计算一个东西,那这个东西就不再是一个例举了,而是一个例,ok这是一个力。
而且更加直观的是什么呢,就是我假设这个力是什么,这个力是加在质心上的,然后他的目标是把至今推到目标目标方向的,这个执行目标的啊,目标至新位置,那当然其实这个知佳丽在质心上这件事情。
本质是没有任何这个真实的这种可能性的,所以本质,所以它本质这个因为它是一个vtual false,我们是假设有一个力加在质心上,但是这个力不是真的加了,而且时间也加不了。
我是说我通过一些关节力矩来实现类似的效果,ok有时候我需要计算一些关键例举,用这个甲亢病transpose的方法,去计算一系列的冠军列举,它能够实现一个类似于把一个虚拟的力,那怎么算的呢。
其实本质上跟前面一样,就是说你是可以用质心简单,你对应关节的位置,然后叉乘啊,这是一个向量吧,差成这个f,那就是得到了那个关节所需要加的例句,当然其实你有些时候还是需要注意一下,这个顺序的。
就是方向问题,因为如果说你比如从root向下和root向上,你这个加了例子top的方向可能是不一样的,这是要特别注意一下,那通常来讲呢我们可以通过在这个力啊,就这我们其实上半身的关系可以。
一般来说不用关心,因为主要是下半身保持平衡,我们其实主要关心这个腿上这几个关节啊,就是hip nee,就是这个大腿根这个髋关节,然后膝关节和脚踝关节,通过这几个关节不就六个关节吧。
当然就是在每个国家加相应的这个例句啊,就ja in transpose算例句,就大概可以实现这样的一个平衡的效果,那除了这个平衡之外,实际上我们还可以实现更复杂的效果,比如说这个它可以是一个什么呢。
不只是一个这个平面的这个projection的这个这个差,我们可以比如说这个c目标函数,可能是一个有高度的,比如像这个角色,他就站起来蹲下,站起来蹲下,我们可以怎么实现的,我们可以通过通过这种方式实现。
我就把这个目标的c啊,它的高度稍微调一调,比如一会儿高,一会儿低,他把这个目标高度调低的时候,但实际上就下来这个局他会慢慢蹲下去啊,然后调高了还要慢慢站起来,会有这样的效果,甚至我可以加一些其他的东西。
比如说我除此之外可以加一些朝向的控制,就是我在这个这个这个这个virtual false之外呢,我们还可以用pd control,就算一些,比如说跟着这个角色左右转一转呃,这个talk。
那这个top也可以额外加的这些腿上的关节,会让这个角色稍微产生一些,选这个稍微转一转身体,所以这都是可以通过这种方式来实现的,ok这是一个非常简单的实现static balance的一个方式。
那当然这个这种方式实现这个balance是非常弱的,就比如说我可以首先能够很稳的站住,这个没有问题,然后比如说我可以,甚至这个角色可以微微的晃动,可以前后左右稍微转一转,但是呢如果说我推一下这个角色。
推的小的时候是没有问题的,就他可能让这个角色看看,来往前往前往前清洗了一下又回来啊,大概会有这种效果,但是呢我稍微推得大一点,比如说这个角色必须要这个往前走保持平衡了。
那这种情况下这个这个这种控制就不work了,我就需要其他的方式来控制的,当然这方面其实还有一些更fancy的一些,更加这个漂亮的一些工作啊,就比如这09年的一个非常有意思的一个文章。
他就是说除了这个平衡之外,我们前面这个控制时间,是假设这个角色是不动的啊,就是它是没有速度的,但是我这个觉得有速度,我们其实可以额外的控制什么呢,就是除了控制我的这个质心的位,置和这个位置之外。
我们还可以控制这个最新的这个,动量和角动量啊,就是就是其实本质上来说角动量,比如我想让角动量尽可能尽可能小,那它其实会有相应的效果,其实想象一下,人在很多时候走路的时候。
你也是在尽可能的保持这个角光量比较小,比如想想走路,就是人正常自然的走路的时候,你会不由不由自主的摆手啊,左右去这晃动手臂,为什么呢,其实本质上来说,你是在补偿你走脚的,这个走路的带来的角度大的变化。
比如说比如说我脚,这个就是不在没有顺拐的情况下,你会计算会发现手手的摆动所带来的角动量,跟脚的摆动带来的角动量,会多少会有一些这个count balance,那他会互相抵抗一部分。
这话整个身体的角度量是比较小,那这样的话更加稳定。
那如果说比如说我走顺拐或者把手揣在兜里,时间你会有额外的能量去去,去去控制一个角动量,那当然这个这个方法具体的细节我就不讲,我只是说就是说这个从思路上来说,它可以在控制,通过控制角动量来实现一下,更加。
比如说这个人在很动作幅度比较大的情况下,也可以保持原地平衡这样的一个效果,但除此之外呢,他还是去求解了一步优化问题,我们前面讲的轨迹优化时间是,我们是优化了一整个轨迹,那这个轨迹可能一秒钟长。
那其实在这个方法里边,其实我们实际上那个轨迹我们可以优化一步,那通过这优化一步,我们可以得到我在下一时刻需要加多少力,来实现,我的目标是这个对这个角动量,动量和角动量的一个目标控制。
那通过结合这些方法呢,我们其实它是可以实现一个,非常看起来非常稳定的,一个一个不倒翁的这么一个效果,但本质上来说还是一个static balance,就是说他其实还是一个静态的。
一个一个局部战力不动的一个平衡,但实际上很多时候,我们很多动作实际上是不是一个static balance,就static balance的意思是什么,就是我们总是希望我的3d max。
它是在sport的这个支撑点的这个这个下边的啊,这通过这样控制,我们,我们实现整个控制过程都是保持这个这个状态,它是一个静态平衡,但是我们很多时候,比如说走路或者跑步,或者很多其他动物。
其实走路是一个非常典型的,人的走路其实不是一个static balance,人走路的时候,你是不停的把你的质心再往下落,就是你在不断摔倒的这样一个过程,但是你摔倒的时候。
你刚好把你的脚移动到一个合适的地方,又让它停止出来的,所以这些人走路,因为人人总是要偷懒嘛,就是因为摔倒这样一个过程,实际是可以帮助你利用这个重力势能啊,来来增加你的速度。
来减少你的使用的这个这个这个力的消耗,所以它是一个非常典型的一个动态屏,它不是一个静态屏,那这种情况下,我们该怎么控制一个角色去保持平衡,那这其实是一个另外一个问题,那我们这今天的课程就不会讲这些。
我们会在下一个下一节的课程做进一步的介绍,ok那回顾一下,其实我们今天还是说按照衔接,我们上节课的内容,我们把我们pd控制,就是比例微分控制的这个一些性质啊,我们把它讲去讲完。
另外呢讲了一些关于这个轨迹优化的,一些基本知识啊,通过轨迹优化啊,包括c m e s这样的一个啊directive free的方法,我们可以优化非常复杂的这种运动控制啊,开环运动控制。
那为了能实现更稳定的控制呢,我们通常还是需要一些这种闭环的,也就是这个啊反馈控制,那防御控制它会根据角色当前的状态和目标,去实时更改啊,我的这个控制的参数,那当然我们其实也是一个做一个,非常简单的例子。
我们讲了一讲如何通过一个pd控制啊,加上一些比如说virtual false或者jctranspose control,来实现一个原地平衡的这样一个效果,那我们还有一个理吧啊,我们下一个会把这个讲完啊。
就是我们通如何去实现一个走路的控制啊,通过这种因为走路是一个动态平衡的过程,该如何去实现一个动态平衡。
ok那以上就是我们今天的主要内容,那我们今天的课程就上到这里啊。
GAMES105-计算机角色动画基础 - P12:Lecture11 Learning to Walk - GAMES-Webinar - BV1GG4y1p7fF
好的,那么回到我们今天的这个这个内容啊,刚才的刚才我们说的,其实我们今天我们上节课讲,就是前两节课讲的主要的内容,第一节课我们主要是讲了一下这个物理仿真,那就是我们如何来仿真一个虚拟角色。
那接下来第二节课呢,我们主要讲了一下如何去控制一个虚拟色,就是如何让一个虚拟角色能够保持一个姿势,那上节课其实我们主要是讲的是,在这个基础之上呢,稍微讲了一点反馈控制。
那反应控制我们当时实现的是一个什么呢,是一个静态的原地平衡的这样的一个控制器,当然这个原力平衡其实呃可以完成一些工作,就比如说结合我们前两节课讲的一些内容,比如说我们的跟踪控制啊。
我们可以让呃控制器去跟踪一些,比如说这个上半身,比如手肢体的一些移动,那在下半身的话,我们可以使用我们上节课讲的,比如说这种啊利利用比如说这个啊雅克比啊。
在后面transpose control来实现的一个平衡控制器,那其实可以让这个角色呢一边平衡,一边能做一些动作,当然这个其实大家想想也好,像我们这个工作这样一个非正半天劲,其实做的就是一个平衡的。
一个,就是其实还本作家好像就是一个就是一个跟踪,一个动捕数据这样的一个效果,但实际上呢如果大家当然我们是作业,其实也会有类似的内容,大家可以看到,其实在这个过程中,实际上比如你可以看到一些额外的细节啊。
这些细节的话,你用这个纯粹的动作数据的话,就是基于运动学的方法的话,可能是不太容易实现的,就比如说这个人在挥手的时候,其实你的身体会不会有一些这个摇晃,因为它需要去保持这个。
其实对抗这个这个这个这个平衡带来的,这个就是说比如挥手,可能带来一些这个角度的变化,那么其实身体也要随着这个这个反作用嘛,它也会向他摇晃,那这些细节的话,其实是会带来一些更加真实的这个。
那这个这个这个动作的动作的这个感觉啊,那当然今天呢我们其实在那个昨天那个基础上,我们再稍微多讲,再进一步啊,就是说我们其实只学会了,如何能够站在原地平衡,但是与原地平衡的话。
其实这个还是能做的事情太少了,我们其实很多时候是希望,至少这个角色能够能在这个场景里移动,那这其实是我们对这个角动画的一个可控,角色的一个基本要求,当然移动这件事呢,其实对于一个啊基于运动学的方法。
就是比如说我们前面讲这个运动合成,那移动这件事情非常简单,因为我们直接在它的关节上,在这个人的这个身体上啊,我把它设置成一个比较合适的一个位置啊,比较合适的一个姿态,那个角色就自然就移动了。
当然我们要特别注意的是,我们不要把这个位置射的不射射射射的太差啊,射的太远,那你可能就看到这人就在不停的瞬移啊,那这就肯定显然就不是真实,但是对于物理学他来说,其实很大的一个问题在于什么呢。
就是说我们不能直接去控制一个角色的,全局的位置,那我们其实只能通过让这个角色,比如它跟地面有一个交互,他给地面一个力,那这个地面会给他一个反作用,反作用力,那这个反作用力能推这个角色向前移动。
那这个过程时间就很多时候,就在于我们该怎么去规划这样一个反思,这样一个全身的这样一个控制,能够让角色能够动起来,a不思,那我们今天其实主要内容还是稍微相对来说,不是呃比较少的。
我们只是首先简单讲一下这个走路啊,实际上在过去的啊,应该说在深度学习起来之前啊,就是说在这个过去20年,其实从零呃,应该是从2000年左右吧,2000年的前10年或者2000年前15年。
就是在物理仿真这个角色中,就是基于仿真的角色动画这个方向,其实大家主要研究内容还是走路啊,就是实际上走路这件事是非常难以实现的,其实这不只是觉得动画啊,其实就像我们常见的像这种机器人。
特别是人形机器人啊,其实最近马斯克这个他们不是搞了一个公司,然后然后最后还有一个,最近还有一个新的机器人,这个这个发布啊,其实还有一些其他大家非常非常熟悉的,像是这个boston dynamics。
不是那不是在努力的这个机器人,其实还有再早一点的,其实现在红的那个本田啊,红打啊,本田的这个asio啊,10年时代是2000年,走2年之后到2007年左右吧,其实也是非常知名的。
这样的一个双足的人形的一个机器,那当然现在其实这个商做商人机器人,这个工资也蛮多的啦,比如像国内有一些像ub选啊,其实也是做的这个相当不错的,这样的一些一些工作,那当然其实我们在深度学习之前啊。
就是实际实际上是在深度学习之后,其实这是这两个领域,其实也是有很大的相关性的,应该在深度学习之前呢,我们见到的很多情况都是我角色动画,因为本质上来说我们是在仿真一个虚拟角色。
但这个虚拟角色比起真的机器人来说,他的约束啊会更加少一点,但是我们大部分情况下,其实还是希望还是采用了很多在机器人里面,特别是双足机器人领域啊,使用的一些技术,然后把这些机术拿过来。
去驱动一个这个仿真的虚拟角色,那当然现在其实,因为我们这个在特别在深度学习这个这段记,这个是这段发展之后呢,其实我们看到这绝动画,大家可能很多方法都是来自于比如深度学习,深度学校学习这种方向。
相对来说对于这个传统机器人领域的这个控制,会就是控制控制策略的这个使用呢,就相对来说稍微少一点,但是呢我觉得其实作为我们这门课嘛,我其实也是觉得这样一个机会,我们稍微讲一讲机器人控制。
这边的一些一些基本内容啊,可能也是对我们这方面的了解会更有好处,难道我们今天主要是讲了一些,讲讲这个以下几个方面内容啊,首先是关于这个走路啊,以及这个走路的一些相关的一些一些这个分啊。
比如说我们如果分割如何去定义平衡,然后另外呢我们就举三个例子来讲一下,我们在过去一段时间怎么使用这个简化模型啊,怎么使用简化模型来实现一个走路的控制,那当然这个工作相对来说比较早。
都是都是零几年到10年左右的工作,那当然我们其实这个啊,对我们本来计划的这个lap 3和p4 啊,就说我们这个仿真里面会有两个这个作业,那这两个作业呢我们其实因为时间的关系啊。
我们可能会把它合成一个实验啊,但本但时间总体内容不会差很多的,那其实我们其中一个实验,就是希望能够作为一个挑战任务呢,希望大家能够实现一个啊能够步行的机器人,那当然你不一定使用这节课讲的方法。
也许可以用下节课讲的继续想要学习的方法,也可以同样的完成这样的工作,ok其实走路应该说我们大家都是非常熟悉的,因为啊因为这个差不多是每个人都会走路,然后走路实际上从因为毕竟来说。
这是大家都了解的这样一个一个动作,而另外一方面,其实走路整体来说是一个相对来说比较稳定的,一个一个动作,没什么稳定呢,因为它比较慢啊,就是很多时候慢的情况下,我们可以有更多的时间去控制。
所以实际上不管是在啊生物学,生物学,医学啊,机器人其实对走路的研究都是蛮多的,但总体来说呢我们可以简简单的去把一个走路,就是如果说我们不加任何的,比如说像这种风格化呀这样的一个约束。
那走路它其实就是一个啊左右左右腿啊,两条腿交替移动的这么一个过程,那在这个过程中,我们其实通常来讲会把它定义一些这个量,比一些一些一些这个名词啊,就比如说像这种single support。
就是我一个脚在空中摆动的时候,另外一个角落在地上,其实那个角就是由他自己来进行,这个就是支持这个整个身体啊,其实有时候也叫single stance,因为他也是一个脚去去站在那里。
然后呢走路其实会有一个特定的,就是特殊的一个时间,就是其实在某一个瞬间,会有两个脚同时在地上啊,这是其实走路的一个特点,就是这个这段时间是double dance,就是两个脚都是在地面上。
然后走路其实是不断的重复,这样的一个这样的一个交替的过程,然后就是每个角分别成能成为一个single stance啊,这个这个支撑脚啊,另外一角是一个摆动脚啊,以此类推。
当然如果说我们把这个走路的这个时间啊,我们就是把左右脚接与地面接触的时间,和右脚与地面接触时间,那这样画出来的话,那你可以看到,其实从时间上来说,他肯定是有一定的重合的地方。
重合的地方呢其实就对应的这个single stdouble,stance的,这个就是双腿支撑的这样一个,这样这样一个阶段,那如果说只有一条,如果不下不接啊,不接触的地方。
其实就是这个所谓single stance的这个阶段,那其实有另外一种就是跟走路相对的,其实就是跑步,其实跑步就是就是实际上我们从定义上来讲,什么是走路,什么时候跑步,就是跑步是没有这个重合的。
就是没有有一个fly的face,就是一个飞行时间,那这个时停时间就是说我有一瞬间,我的左腿和左脚和右脚同时离地,那这个时间他是那这种动作,其实就可以就他就不再是走路了。
可以把它定义成跑步或者一些其他的动作,其实大家如果是对这个比如说奥运啊,比如田径感兴趣的话,大家知道有一个项目叫竞走,那竞走其实有一个非常主要的规则,那规则是什么呢,就是说不允许啊。
有这个肉眼可见的哈哈就是飞行时间啊,就是说你必须要保持至少有一个角呃,跟地面接触,那你才是走路完了,否则你就不是走路,你是跑步了,所以实际上大家比如看节奏比赛,你可以经常看到这种犯规。
很多都是对这种犯规啊,就是其实因为走相对来说肯定是跑跑的更快,但是这个你要是在这个,尽可能接近跑的状态下去走,那这其实是竞走他们做的事情,那当然我们这节课我们不会研究跑步,我们其实主要还是研究走路。
我们上节课其实就比如我们在走路的时候,就是我们及时走路,就是两个角,我们总是交替的向前移动啊,其实虽然说我们是一会儿一个角直升力,一会另外一个角直升,但总体来说两个角是在不断的交替向前移动。
那在这个过程中呢,实际上我们其实上节课讲了一些内容,比如说我们要想实现平衡,其实一种策略去实现走路,就是利用我们上节课讲的,关于这个静态平衡的这样的一个方式,其实静态平衡。
我们上节课没有做一个详细的定义了,就说我们其实可以可以简单的认为啊,静态平衡就是说这个人啊,这个这个东西,这个对象它在基本上不动的情况下啊,我可以怎么放,他怎么怎么样才能保持平或者叫静力平衡。
因为它可以的,至少我可以保证我的,比如说我的这个3d max,我的质心啊,跟我的这个旋转,就是可能会导致我旋转这个这个这个这个轴啊,我总是在它这个旋转轴上,或者在这个在我的polygon的里边。
能保持我的平衡,那比如走路的时候,我们其实可以类似于类似于一个风格,就比如说我在double a single dance这样一个瞬间,在三个时段的时间,我可以我知道我一只脚着地啊。
那这个脚本身就是我的这个polo polygon啊,它是我的支撑支撑的这个面,那我其实可能在我的控制过程中,我们是需要我的3d max,我的知心啊,始终保持在这个在地面的投影。
始终保持在这个这个sport polygon的上边,那接下来在double down的时候,其实就是这就是走路,为什么我们讲就double stance是一个比较呃简单的。
就是可以帮助我们去实现这个走路呢,就是因为double stars实际上两个脚同时落地的时候,我们有一个更大的这样的一个swap polyon,就是这个这个支撑的这样的一个区域。
这个区域其实包括了两个角的一个背包啊,就是它的凸包的这样一个空间,而在这种空间呢,其实在,如果说我们要通过这种方式来实现走路的话,我们其实是需要通过这段时间,把我们的这个3d max啊。
从从从原来这个角,然后通过这样一个double sponse的fdouble support啊,double stance的这个这个这个这个阶段,然后移动到另外一只脚上,那这在另外一只脚,他在实习。
他在这个single stance的时候,那我们其实这个这个支线就可以保持,一直保持这样一个平衡,那当然这是一种实现走路的策略,而且实际上,如果其实你是真的是可以,通过这种方式来实现走路的。
但是这个策略上的需要可能需要做一下,做一下这个做一下改变啊,做做一下这个设计,当然这个最大的问题在于什么呢,在于这个static balance啊,如果大家大家将来做这个实验的时候,大家可以去尝试一下。
也就是发现其实它是非常不稳定,因为它只能减,就是勉勉强强啊,保持这个这个角色姿态的一个一个平衡,但是呢就是因为本质上来说,它是假设啊,这个角色是处于一个不动的状态,那么如果说我只觉得正在动。
那其实这个假设是被破坏的,就是因为正态动会带来什么问题呢,就是会带来除了你的这个这个,就是它会带来一些这个动量的变化,特别是角动量的变化,比如说我这个人正在向前移动,我只能一个脚站在地上。
那我其实移动会对,相对来说这个角旋转之后会有一个角动量,那这个角动量我们该,如果说我们不能很好的去平衡这个角动量的话,那我其实也很难去啊保持我的身体的平衡,所以实际上我们通常来讲就是think us。
就是static balance,我们可以实现一个非常慢的,就是非常慢速的,一点点的去向前移动的这样的一个走路,但如果想实现更加看起来更加这个灵活的,这个走路,那么通常需要更加仔细的。
就除了对我们知心的位置这样一个空之外,我们还需要对一些其他的,比如这个对这个动量的,这或者角动量的这样的一个控制,那当然这个其实也是后来我们很多嗯,这个机器人领域就是这assim。
就是其实在20 2000年左右的之前,其实很长一段时间,双足机器人我们怎么实现走路,其实很多时候都是通过对这样的一个一个,一个啊动量的这样的一个控制,来来来完成一件事情。
那当然这里其实有一个非常重要的概念,就是所谓的zero momentum point啊,就是我们后面其实很多好几个非常成功的啊,这种啊这个双足七人啊,这个这个这个角色,他其实是指主要还是通过啊。
对这个zero momentum point的控制,来实现一个比较稳定的走路,那什么是zero,我们的炮这个叫零,应该叫零动量点啊,这是一个机器人学习的一个,就是这个双足机器人里面的。
一个非常重要的概念,我们这里可以举一个例子啊,就说这个比如说这是一个人啊,这是我们一个虚拟角色,他其实有很多钢铁,那现在他正处于走路的状态啊,当然看起来像跑步,但是我们认为他是在走步。
那他走路在在这一个瞬间,比如它是一个单脚支撑的这样一个状态,那在这样一个状态下面,我们可以看到,就是我们可以对这个人整体做一个,简单的受力分析,我们可以知道,首先这个人要受重力影响。
其次呢这个角落在地面上啊,这个地面需要给他一个支持力,然后同时这个人又在移动啊,比如这个人可能我有一个加速度,这个加速度可能是我的,因为我正常来讲,比如人往那走路的话,实际上我的速度是不均匀的。
我总是会处于一个这个这个加速和减速的,这样一个状态,那这些时候实际上能够提供这个加速度的,其实是完全是这个gf,就是地面的这个reactor false,这个电源是false,包括什么呢。
包括我们前面讲的这个,或者说它其实本质上就是我们前面讲到的,比如说这个支持力,比如说一个物体放在地面上的,地面会给他一个支持力,那同时如果这个物体有一个移动的趋势呢,那我地面会给他一个摩擦力。
那这两个力合在一起,其实就是我的这个地面,给我的这个啊知识点的这样一个嗯这样一个gif,就是这个这个这个应该叫反作用力,地面反作用力,那当然我们可以为了其实整体这个人的动作啊,就是整个身体的动作。
其实我们比如我们前面可以简单的使用,比如pd pd控制,来实现这个让这个角色去跟踪某一个控制器啊,去跟踪某一个某某一个轨迹,那它就是就是产生了相应的动作,那这里其实在做这个动作过程中呢。
其实我们关心的是说,我们该如何去能够让这个这个控制这个ji,它能够让我们保持平衡,那这个时候我们可以做一个简化,就是我们其实可以把这个上半身整个人啊,把这个上半身所有的动作,把它给这个桶总合起来啊。
就是因为不管怎么样,如果说我们只关心这个角,这里因为它不是一个缸体,它跟上半身通过关节来连接的,那么其实我可以完全可以把上半身,就是整个身体其他的部位对这个角的影响,因为他总是通过这个角跟这个腿之间的。
这个关节进行连接的,所以所有的比如说这个这个,其实上面关节的这个它的运动,其实总最终都是通过这个关节的一些移动啊,关节的这个嗯通过关节施力和施加力和力矩,来影响到最后这个这个肢体的移动啊。
这实际上是一个非常简单的一个非常这样一个,应该叫应该叫这个啊,应该叫isolate啊,就是说我们把这一部分把它给独立出来,来进行分析,来进行受力分析,那当然这个其实如果大家可以回想一下。
其实也是可以想象,比如说我们当时讲过一个两个钢铁,然后中间用一个关节点连接起来,那这个钢铁运动的时候,其实关节点它是作为一个约束,那这个约束呢会给分别给两个缸体一些力啊,当然这个力是会大相等。
方向相反的啊,然后这个力呢能够保证,这两个钢铁在移动过程中不会分开啊,就当他一旦有分开的趋势,我就加一个力把它给拽回来,那这个过程中实际上在我计算完这个力啊,比如说我们通过某种方式。
已经把这个力计算好了,那实际剩下的仿真过程呢,就是我们完全可以不需要关心,另外一个缸体是什么样子,我就只关心这个钢铁,我知道他在这个时候受到这样的一个力,那我只要关心,只要这个观点啊。
缸体按照这个力的方向移动,那其实它就不会分开,所以说其实刚才我们就是就是,就是刚才我们这个这个嗯,就是这个回到我们刚才这个例子啊,就是实际上本质上我们这个人啊上面多复杂,其实都无关紧要。
因为它最终能够跟这个角,就是只要对角进行交互,其实就只能通过这个关节上面加的力和力矩,来进行完成,所以说假设的时候我们已经知道了,在这个关节上,比如这个是一个踝关节啊,我们在这踝关节上加了其他的。
身体的其他部分啊,部位给这个环节加了一个力,加了一个力矩,那这个力可能怎么算呢,我们可以通过解的运动方式来得到,那同时地面会给这个环环节一个力,这个力我们认为它是施加在一个点上。
但实际上地面给他力并不是持加在一个点上,因为我们想象一下,比如说我们正常来讲走路或者站在那里,其实我们脚比如脚是平平平的,这个站在地上,那实际上你这个你跟地面接触,脚跟地面接触是一个面。
那这个面上其实每一个点,都会受到地面的接触力啊,或者说同时你也是会受到地面的摩擦力,那这种情况其实我们可以,比如说我们可以假设我们有若干个点啊,然后每个点上都有一个力,都有一个这个力。
但是力的大小我们就不关心了,我们就是知道这有这么一个力,然后这个力每个力啊,是施加在对应的这个这个某一个点上,就是立fi,那我是加在pi上,那当然这个利他总是很就是由两部分构成。
一部分是地面给我的支持力啊,总是竖直向上的,另外一部分是我的摩擦力,那摩擦力永远是跟这个基础面是平行的,那这样呢是一个,那这是基于我们的这个摩擦模型,那这是我们这个力的这样的一个一个一个构成。
那这样的基础之上呢,如果说我们因为这这这里有很多力嘛,而这是一个钢琴,所以对于钢铁来说有一个什么好处呢,就是说不管我加多少力,这个我总是可以认为这些力是一是这样,不好意思。
我总是可以认为这些力呢是等价的,施加在某一个点上啊,比如说这个点p啊,这个点p在哪里其实都不重要,但是我是总是说我认为这个力是等价的,加在这个历史啊,加到一个点p上啊。
那这个等价需要是这带来什么样的效果呢,就是说我可以认为这个这个接触面上,所有的力的的这个和啊,是是加在这个点上的这个力,然后同时呢因为每个力原来是只有力的作用,但如果说我们把它集合这个集成到一个点的话。
那我们其实先就是应该说是每一个力啊,每一个原始的这个力其实都会对这个物体,比如说相当于它的,至今都会有一个有一个这个啊力矩,那如果说我们把所有力合在一起的话,那其实相当于在这个点上。
我们也会有一个合力矩啊,加在这个点上,所以这样的话,其实我们回想一下,我们以前讲力和力矩的这样的一个公式啊,就是例呢这个总得利,那其实就是立的这个每个力的这个求和,那力矩的话。
其实是每个力矩相对于我这个,我认为他施加力的这个点啊,然后他的一个差成来进行求和,得到这样一个关系,那当然这里其实我们可以进一步的假设,就是实际上如果作为了简单起见,我们可以假设这个地面是水平的。
就是同时是水平的,并且是平坦的,那在这种情况有什么有什么结果呢,就是说我们可以啊,比如这个p啊,就是这个这个施嘉丽的这个点,那我们其实也可以,也可以认为它就是在地面上啊。
就是说这里所有的施加力的点和每一个f,它最应等于施加力的点都是在平面上,同时我们也可以假设这个p是在这个地面上,那这种时候下这个p和p i和p之间的连线啊,那肯定是跟地面是平行的啊。
这是一个这是我们的一些假设,但这个假设其实也是非常非常常见的,因为我们知道我们一般大部分常见的场景,我们在房间里走路,但是在这个基础上呢,我们可以把前面这个公式做一下简单的变形啊,就首先前面一步fy啊。
它是代表了一个竖直向上的力,然后fx z它是代表着一个水平方向的力,它水平方向具体应该是竖直方向,是一个确定的方向,但水平的话,那其实是整个水平平面里边任何一个方向,这个我们其实是不是这个不能确定的。
那我们可以把它做一个简单的这个合并啊,这个嗯所以下分配啊,其实可以前面这一项,因为p减去pi啊,pi减p它是跟地面平行的,然后fy啊是一个跟地面垂直,其实只要是f d y跟地面垂直。
我们就知道这个插成肯定是水平的,然后第二项呢就是因为前面一项是平行,跟地面完全平行的,后面一项呢它也是跟地面完全平行的,所以他们两个差成,我们用六手定则可以知道,他肯定是在竖直竖直面上。
所以说实际上我们相当于是什么呢,我们相当于是把一个地面的总的,这样的一个例句啊,gr和例句,那我们可以把它分解成沿着地面平行的部分,就是在水平面上的部分,和这个跟地面垂直的部分。
当然特别大大有要有一个印象,有一个想有一个概念,就是说当我说它在地面垂直的时候,它其实是沿着垂直那条直线啊,那个轴的一个力矩,它是一个旋转的,就相当于我我带的效应是沿着那个轴旋转。
然后这个x y x z就是在平面上一个例子,比如说这个比说一个例句,是这个方向是沿着这个边沿的这个方向,那实际带来的效果是什么,是沿着这个轴进行旋转,那可能就是把这个这个角向上翻转,那达到这样一个效果。
那我们可以进一步的这个做一个这个变形啊,达达到这样的公式啊,其实就是把前面这个pi减p,因为p是一个共用的,我们可以把这个p提取到这个球号,求和号外面来了,就得到了,sorry,得到这样一个公式。
那这里有一个问题啊,就是这样一个公式,因为这个p是一个随机选取的,也不是随机选,就是我们是在可以在这个平面上,随便选任何一个地方选的一个参考点,那我们是不是可以找到一个参考点,那这个参考点之下呢。
在这个平面的这部分这个力矩啊,相对于这个参考点力矩是零,有没有可能找到这样一个点,但实际上你可以大概从这样一个公式的,这个形式,大概也可以也可以看得出来啊,就是似乎是有可能的。
只要前面这一半跟后面这一半相等,那它就是零,所以实际上这个点是有一个确定的点,这个点通常来讲我们可以把它叫做这个center pressure,就是这个脚踩地上那个那他这个压力的重心啊。
就是center pressure,那它定义上来说可以就是我们每一个点啊,跟正心呢跟质心的其实定义很像,至今我们怎么定义的,我们是每一个缸体的位置乘以它的质量,然后加权平均得到的重心。
那这里其实就相当于,比如说每个点它的位置上有一个力啊,那这个力其实我只关心这个竖直方向啊,输入方向的压力,因为那另外一部分是摩擦力,那我我用这个压力的大小,那这个平均值啊。
就是对应的我这个这个这个center pressure,压力中心的这样一个位置,那如果说p是选了这样一个点嗯,选了这么一个点,那我把这个带入到上面这个公式,那我们其实可以比较容易的得到。
最终这个也就是先绕着这个点,就所有的力,所有的这个支持力,我加上摩擦力啊,绕着这个点,它的这个啊在水平方向的这个例句啊,是零啊,这是一个非常有意思的点嗯,那在这种情况下呢。
实际上首先这个这个合力的大小啊,这个是不会变的,它就是所有力的笔壳,那如果说我选这个嗯这个质心为参考点啊,这个这个center pressure啊作为参考点的话,那实际上所有的力的力矩啊。
相对于这个参考的例句,它是没有水平分量啊,它只有一个数值分量,那数值分量就是说,它只能让它会让这个物体进行旋转,所以这是一个很特殊的点啊,就ser pressure,他有这样的一个性质。
那接下来呢就说我们,假如说刚才假设这个这个角色在这个状态呢,他是处于一个stance face啊,就是说这个是一个角啊,落在地上那个脚其实在stance face里边,其实大家想想我走路的时候。
我支撑那个脚是一般来说是不会动的啊,就是我只是这个这个摆动腿啊,在向前摆动,但支撑腿在这整个过程中是基本是保持一个,跟地面接触的这样一个状态啊,那我们可以进一步的假设,它就是一个始终是保持一个水平。
跟地面完整接触的这样一个状态,ok那在这种情况下,就是通常来讲,这个其实我们我们是说我们是把这样力啊,把这个力把把这个地面给他这个所有的接触力,我们认为是施加在某一个点上,那这个点他是这个嗯。
那这个点我们可以随便选,但是它比如说在一些特殊情况下,我们可以选center pressure,但是如果说我们想这样一个点,就saber有什么性质呢,它就是能够让这个在这个点已然是这个点的,这个例句啊。
他的这个和是零啊,水平水平分成零,但是如果说我们无法测量,无法现在没有办法测量这个每个点,因为他如果要算算的pressure,我需要算每个点上,那到底是加了多少力,但如果这个点我们这个没法测。
我们只知道一个总的力,那这个那就是这种情况下,这个具体这个center pressure它在哪里,我们其实是暂时是不知道的,但是我们可以是可以假设,我们有一个点是满足这样一个条件的。
那么在如果说我们认为所有的这个,所有的这个gr f都是实在这个点的情况下,那gr f相对于这个点这个talk,那他应该是这样一个关系,ok那接下来不好意思,因为这个点啊,因为这个物体就这个角在这一时间。
虽然说他受到了很多力啊,就是说不管身体是什么状态,他总是最终会变成一个,在这个点上加了一些力和力矩o,那这些力和力矩,所有这些力共同作用的效果是什么,是在我是说这个角啊始终在地面上保持不动。
那说明这个角处于一个平衡状态,它在所有一堆力的作用下,就是首先我要求你的力的大小啊,所有的力加在一起应该等于零,另外一方面呢就是说我还要求你所有的力啊,沿着任何一个某一个啊,其实是任选一个参考点啊。
比如说o点沿着它所有的力和力矩啊,也参相当于这个参考点的总的例句和总的moment,总的这个这个这个这个嗯重量啊,哎应该叫什么来着,总的这个moment是零啊,这也是我们这个平台条件。
因为如果不是零的话,就说明这个东西会旋转啊,就是我们的镜静力矩不为零,那它就会旋转,那它它就不再是一个平衡的一个状态,当然这个这个相当于这个参考点,那我们其实可以算出它的总总的这样一个力矩,是多少呢。
其实是就是说我们可以用每个点示例的,到这个参考点的连线差成这个力,就得到了这样的一个一个一个公式,得到这样一个公式呢,我们可以进一步的这个做一下,做一下这个判断啊。
就是说实际上我们可能只关心这个水平方向啊,因为这个东西本质上是一个合力矩啊,是一个合理举,但是合力矩其实如果是它等于零的话,说明他的水平方向啊,就x x z方向的这个分量和它竖直方向。
就是y方向的分量应该都等于零啊,都分别等于零啊,才能保持它等于零,所以说如果说我们只是先,如果说我们只关心这个水平方向的分裂的话,我们其实可以看到一些,我们可以只把这个上面这个左边部分好的。
这个xz方向的这个分量给拿出来,那这里其实要注意的是说什么呢,就是说嗯我在我们这个假设之下啊,就是我们的地面只有一个竖直方向的力矩啊,经历,那如果说我们只考虑水平方向的话,那这个例句就是没有了。
我们其实最终就是引发原来这里是五项,现在只有四项,因为这个这项被丢掉,ok那另外一个特别注意的是就是什么呢,因为mg就是重力始终是垂直向下的,直接向下的呢,其实它的水平分量其实跟数值分诶。
他其实就没有数值分量,就它所以竖直向下跟一个东西跟一个做叉乘啊,那他其实肯定是跟它垂直的,他那个水平方向,所以说整体来说是这样的一个这样一个公式,那有这样一个公式呢,实际上这里蕴含了两个方程啊。
因为本质上来说这是一个sz嘛,我其实相当于把左边的这个二次二维的部分,就是只有x这两个两个坐标,然后它相当于是这两个坐标的值分别等于零,那在这里边呢,如其实u的位置我们是知道的,o的位置是我们自己选的。
所以说其实也是知道的,这个ex也是知道的,因为它是这个质心啊,就这个腿的这个就这个脚的这样一个质心,然后这个力的大小,如果说都假设我们知道的情况下,那我们唯一不知道就是p了。
但是p呢又是在我们知道它是在水平面上,所以它其实只有两个未知数,所以这个方程里面我们是可以把p解出来的,理论上来说,就是我们可以通过解这个方程,来算出这个p点的位置,那这个时候找到这个p点啊。
其实这个就是一个非常重要的点,就是它就叫做这个zero momentum point啊,就是我们的z m p zz m p为什么叫z m p呢,因为它实际上是在我们假设,有这样的关系的情况下。
我们算出来的p的位置,也就是说时间,另外另外一个角度来说是p是满足,使得我这样的一个旋转的力矩,等于零的这样的一个状态,那另外一方同时呢,它也其实也是让我这个水平分量,就是总的合力矩的水平分量等于零。
那满足这样的关系,所以说我们这为什么讲这p叫零立据点啊,零零zero one的point啊,这个中文我还真不知道怎么翻译啊,就是这样一个000力矩,灵力灵力局点的这样的一个,这样一个这样一个东西。
但是呢领略显为它是成立的条件是什么,它是条件是说p是在sport polyon里面,比如说这个p点是一定是在这个角的内部,它才它才是有意义的,但是有意义的,因为实际上我们在求解这样一个方程的时候。
在写这个方程的时候,实际上我们只是做了一个假设,我们只是假设说这个地方等于零啊,但这个东西它有可能不是真的,这个假设也许不一定是真的满足的,但是我在这个假设之下呢,我们是可以求出一个p。
就是这个p应该是说什么呢,这个p是能够满足我们这个假设的,一个点的位置,但是呢如果说我这个力啊,比如说我这个人可能处于一个正在倾倒的状态,正在往前摔倒的这样一个状态,那这个时候你是依然能够用。
通过这个方程算出一个p的位置,那这个p的位置,你会发现它是在我这个角的外边啊,就是本来来说,比如正常来讲没有平衡的,没有摔倒的时候呢,其实这个p是在那中间的,那如果说你某一时刻发现诶。
我算上这个p是在角的外边,这个说明什么呢,这个说明这个p是不在,在这个情况下,他不是我们前面提到center pressure,因为center pressure从定义来说它是我力啊。
外力加在这个是这个力矩上啊,加在这个角上,他这个所有的外力的这个这个家庭平均点,那如果说不管怎么样,因为所有的脸都是加在角的内部吧,那所以说你加权平均点肯定不可能跑到外面去。
所以说如果他如果算上p在外面,那它肯定不是cnpsh,但因为它不是ser pressure,那所以其实我们知道就说我们所有的力啊,就真实我们家的力相对于这个点,它的合外力应该是不为零。
因为只有sd branch才为零,所以是这样一个条件,或者在进或者另外一个角度讲说,如果说我们有另外一个点p撇,那这个撇是这个真实的这样一个center pressure,那我们可以得到什么呢。
因为p是能够让这一这个东西等于零的一个点,然如p撇跟p是不相等的,那我们其实可以可以推断出,那在p点的情况下呢,这个上面这个公式就不等于零,那上面的公式是什么呢,上面这个公式实际上是我们家的这个腿上的。
这个这个合外力矩,那它不等于零代表什么意思呢,代表了这个这个角在这一瞬间,它的合外力矩不为零,那合外力矩带来就是水平方面的合外力矩啊,他带来什么问题,就是说因为水平方向会让这个角色这个角啊。
沿着这个平面的某一个轴进行移动,但实际就相当于这个角会往前翻转啊,但我现在因为我这个有一个静力矩,它会让这个角去这个比如说抬起来啊,其实抬起来之后呢,其实经常来说他会更加变得更加的不稳定。
就虽然是小就翻就翻过去了,其实对应的人就是其实就摔倒,所以总的来说呢,就是说我们其实z mp其实是在那个运动,就是双足机器人啊,就是机器人控制领域,这是一个非常重要的一个概念。
就它是一个非常重要的一个啊指标啊,就是告诉我们这个现在这个这样一个角色,他是不是处于一个动态平衡的状态,就是它是不是同时,又能满足我的这个力的平衡啊,又能满足我的这个角动量,就是动量上就是动量和力矩啊。
是互相平衡的,这样的话他不会进不会进一步的翻转,所以你从另外一个角度讲呢,就是其实作为一个指标,我们其实可以从某种程度,某种程度上来说,如果说我们在让在控制这个角色的时候。
我始终能够保持我的这个z m p,处于我的这个这个支撑的sport polygon的里边,那我其实就相当于保证了这个角色是不平衡的,那这里就问题就是说,我们该如何实现这样的一个平衡。
当然这其实是一个非常非常复杂的问题了,就说我们前面只是讲了一个cmp这样一个概念,但是如何控制它啊,这竟然是一个相当于是另外专门有一,专门可以用111门课啊,来进行介绍的一个一个内容。
当然我们这里只是讲的简单的讲一讲,就是说从思路上我们该怎么实现啊,就这里其实是一个问题,就是说嗯如果说这是只是一个嗯,只是一个物体啊,或者说一个物体上面可能加了一些外力,那我们其实相对来说是这个东西。
是相对来说比较好,比较容易分析的,我们可以很密,比较可以很很很很容易的写出这个物体,它本身的这个力学方程,然后通过这个力学方程,我们可以比如使用优化啊,或者使用这个我们下节课会讲的这样。
比如说这个最优化的控制啊,这样的一些方法来实现对它的控制,但是呢对于人来说,人通常是一个非常复杂的一个系统,上面有一大块,比如上面有二三十个不同的这个缸体,然后这些缸体它每一个受到的空受到干扰。
可能都会影响我的力力的控制,所以整体来说,如果说我们只对整个人进行分析啊,进行控制的话是非常困难的,所以很多时候就是在,为了能够让这个问题更加可控,通常来讲呢,我们会使用一些所谓的简化模型的方法。
简化模型做的是什么呢,就是其实他是从人啊,或者一个非常复杂的这样一个角色,比如人或者一个双足机器人啊,因为他可能这个身体有很多状态,或每个关节的位置啊,每个关节的旋转速度等等。
其实都会有非常都会影响我控制这个状态,那从这些基础之上呢,我们是希望能够找到最关键的,最影响我们这个运动这个平衡性的一些量好,然后把这些量单独拿出来,建立一个简化的模型啊,通常来讲呢。
我们会不会把这个知心啊,因为质心的位置和这个这sport polygm,就是我们这个支撑面的这个位置,其实或者支撑点的这个位置,它们的相对关系其实是非常相关的,所以很多时候我们会把这两个部分拿出来。
然后可能加一些其他的一些信息来构成一个好,基于这些信息的一个简化模型,或者一个抽象模型,那这个车开门就好,有很多种不同的方式的,我们真的只是画了几个图,是一些一些一些一些经典的一些抽象模型,那接下来呢。
实际上我们建了一个抽象模型之后呢,它是一个虽然它是它是一个简化的模型,但它本身其实是满足一些这个物理规律的有规,那我们其实可以仿真它的运动,我们甚至可以仿真这个东西,在一些外界的控制之下。
比如说我加一个力啊,在这个减号模型上加一些力,那这个力它会影响这个简化模型运动,从而带着个减号模型产生一些新的轨迹,那这种情况下呢,我们可以通过去控制啊,去规划这些力,来使得我这个减号模型生成一些轨迹。
那这些轨迹可能需要满足我的一些要求啊,比如说我希望这个知心啊,因为这之前是通常这种简化模型的一部分,我希望知心的轨迹啊是向前移动的,那就相当于我其实现,因为之前是这个角色的一部分嘛。
其实相当于角色其实会会相移动,那当然这个简化模型只会告诉你,至心是怎么移动的,但是呢,你最终还是需要把简化模型所规划出来的,这样一个执行轨迹,再用这个机器人去啊,这个释放出来啊,就使用出来。
那这个其实有很多种不同的方式呢,比如说最简单的方法,我们可以用inverse kinematics啊,我们可以用i k去根据,比如这个至今的位置加上我,比如我这个腿和脚的位置,那我可以反三。
我可以这个用ak就算一个腿的一个姿势,或者全身的姿势,然后再用pd控制去跟踪这样一个姿势,那就大概上可以实现这样的效果,那其实还有一些更加复杂一点的。
比如说我可以通过id inverse limit的计算,来,从我这个至今的移动来估计,我全身该需要加多少力矩啊,这其实是一些一些这个,简化模型的一个使用方法,当然一个比较简单,也是一个非常经典的例子啊。
其实这是应该是003年的一篇工作,那他其实就是说我建立了这样一个简化模型,就是他是正常的,他控制键控制是一个机器人啊,是一个这样的一个机器人,但是呢这个机器人它很复杂,所以我可以把它简化成什么呢。
简化成一个桌子,一个桌子,桌子上面放了一个物体,然后放了一个小车,那这个桌子本身有一个腿儿啊,那个腿其实是我的支撑脚,那这个支撑角其实我们可以算他,因为每个地面会给它机制力嘛。
所以它其实有一个嗯有电这个sa pressure,有z m p我们可以听,就整个这个系统,我们可以计算它的z m p在哪里,那这个时候呢其实我们会发现呢,我因我前面也看到z m p的计算里边。
其实也会有这个系统里边外力,就比如说这个桌子看这个系统,那其实我们需要知道这个车对这个桌子,它的试驾力和力矩,那同样的这个桌子对他施加的力和力矩,其实反过反过来说,其实对桌子啊,对这个车。
对上面这个小车也有相当的这个总体反重力,所以说这种某种就是相当于在这种情况下呢,就是说对于这样一个简化模型,我可以通过控制这个小车在这个桌面上的,这个运动来实现对地面上这个力矩啊,cmp的一个控制。
当然这个这个我们是可以,通过这样一个简化模型,我们可以写出他的这个运动方程的啊,就是你可以做一个具具体分析,来写出这样一个运动方程,那有这样的运营方式之后呢,我们目标是说什么呢。
目标是说希望这个z m p,它满足一些预定义的轨迹,就比如说我们这个这个角色正在向前移动啊,正在两个角之间不停的向前移动,那那相当于什么呢,因为我们的z m p始终是希望他能够保持在sport。
polygon里面的,那回去想一想,我们前面讲的那个两个角,人在向前移动的时候,你的polygon实际上先从这个角,然后逐渐移动另外一个角,然后再移动回这个角,所以说你会看到。
比如说我一个目标的z m p的轨迹,可能是在两个角之间不停的切换的,那接下来呢,实际上我可以通过一些优化的方式去得到,我在这个力这个小车上,它需要采取什么样的加速度,在这个桌面上移动。
才能够使得我的这个z mp满足我这个要求,那因为这个小车本身它有质量,其实相当于这个整体来说,这个小车其实相当于就是我整个这个机器人,它的质心了,然后这个你会发现它之心会根据我。
因为在我跟踪这个z m p的这个过程中,我的知心会产生产生出一个轨迹啊,这个其实就是我的这个规划的轨迹,那在这个过程中你会发现呢,就是先质心的位置啊,其实在这对于机器人来说。
你至心通常来讲是在比较偏重于这个这个,这个人的中心嘛,就是机身中心,比如说可能是我的root关节的,比如说我的这个腰啊那样的一个节点的位置,那这个z m p因为它代表了support polygm啊。
那就是sport polyon呢就是我的脚的位置,所以通过这两个位置呢,我可以通过i k,那可以算出一个这个关节的位置啊,关节的姿势,然后呢,这关于姿势。
我就可以用pd control去让这个角色做出这样的姿势,从而能够跟踪我这个运动的轨迹,就感觉好像是有点有点有,就就这个东西其实就是我们所谓的简化模型了,就是它其实并不是一个非常真实的模型啊。
它实际上是我们为了能够我们可以假设,真实模型是按照这个简化模型是移动的,然后我们通过控制,简化模型来为真实的模型的控制,提供相应的信号,那其实就是我们这个用这种方式,我们可以实现一个比较复杂的一些运动。
比如说这个我可以让这个角色上楼梯啊,我可以让这个角色去走一些更复杂的这个场景,当然这是其实也是这个z m p方向,这工作一个比较相对来说,一个比较经典的工作了,这个也是很早的一些工作。
但实际上用z m p的方法,我们可以实现一个相对来说比较,就是很很自由的。
就是就是很很灵活的一个机器人啊,这个其实也是非常有名的,就是s m啊,刚才也提到了,就是这个本田honda公司,之前做了一个一个一个一个产品,当然这个产品也是很遗憾,我们其实之前也是在很多展会了。
他就是干,就是他其实在各个展会都有些有些这种展示,但是呢好像这个项目现在已经停止了,就是说这个东西最终也没有真的就是商业化,其实可能这个从机器人的角度讲,可以某种程度上来说也是嗯。
就像这个不是波顿动力啊,他的机器人虽然说它非常灵活,但是也是经常会有一些,就是我们可以看到这个嗯,就是商业化还是多少有些困难啊,但这个其实就可以很明显啊,就是说其实可以这样一个步态啊。
就可以很可以很明显的看参数,它是一个z m p控制,就3p控制有什么特点呢,就先我们是假设这个角。
基本上是跟地面平行的啊,因为我们是只是要求这个地看,那它跟地面完整接触嘛,我们前面的所有的控制都是基于这样一点,另外一点呢其实为了进一步的保持平衡,其实很多时候比如这个角色同他一样。
腿是一个弯弯弯曲的这样一个状态,然后整体移动速度相对来说也是比较缓慢的,因为它实际上总是还是需要保持,我的3d max跟sport polygon支持。
相当于只能说在sport polygon这样一个内部啊。
就是你可能到边缘,但不能跑得更远,当然时间s assal,其实除了这个嗯z m p控制外,还有其他其他其他很多的东西了,就是这个实际上是就是我们前面讲的zm p,这个控制时。
应该说只是这个一个非常简单的一个例子,就是当真实机器人里面,其实他用的东西更多一点。
就因为他除了自m p控制之外,它其实还有一些,比如说像是foot plan啊。
就是这个脚步控,脚步规划这样的方式来保持平衡啊,但这是一个之前的一些工作,那当然我们也提到了,其实这种动作你放在机器人上很自然,因为大家想想这就是机器人,但是其实人走路不会是这个样子啊。
就是人走路是什么情况呢,就是人其实相当于始终处于一个。
不平衡的状态啊,就大家可以其实想象一下,就是人是相当于什么呢,就是我们始终啊就我们经常在走路的时候呢,我们的set of max,我们的质心会移出我们角的范围。
或者实际上我们现在max其实始终的就是很真,很少一段时间是在角的上面的,然后再移动,只要你移出了这个角的范围,那就相当于,其实你的人会向前向某一个方向倾倒,那这个时候呢其实你会迈腿啊。
我会把我的脚放在一个合适的位置,这样的话我倾倒一下,我会这个比如我会加一下速,那正好我那个腿的位置能够让我在进行减速,正好是也始终保持这个我我的质心,始终在这两个角之间保持这样一个可控。
所以实际上就是其实这也是一个具有一些,这个生物学啊,基础的一些一些一些一些一个状态,就是实际上从生物学的角度讲,就是人其实是很很喜欢偷懒的,就是说他除了啊像走路啊,或者原地站在那里啊。
就是实际上很多时候,你都是处于这样一个不平衡的状态,就为大家可以想象一下,你在站在地上,站在原地,站在那儿保持平衡啊,就是就是前面是站在那儿的时候,实际上你是属于始终一个,比如说你在轻微的失去平衡。
然后就把自己推回来这样一个状态,但实际上从生物学那边的研究,他们也是说这种方式其实更加省力啊,就比我始终不一直保持我的一个质心和这个脚,保持这样一个非常仔细的平衡状态下。
就是我们这种始终这样一种在降落啊,不停的这个湿气平衡就又恢复成这样,反而是更省力的这样一个状态,那当然这里其实是一个很有意思的一个,一个研究了,就是说实际上我们前面这个讲的一个角色。
实际上都是我们需要一个电机啊,去驱动这个角色去移动,但实际上呢因为刚我们提到,其实走路本质上就是一个不停的摔倒啊,sir不停的在往下往下摔的这样一个趋势啊,同时又在不停的去重新规划。
我下一个角的下一步脚的姿势这样一个状态,所以实际上如果我们把这个结合起来的话,我们其实是可以让这个角色生成一个设,计个机器人,那这个机器人是什么呢,他可以始终在自己重力下,重力的状态下向前摔倒啊。
同时又在不停的就是,把这个角移到合适的位置啊,实际上就实现了一个某种,一种简单的一个走路状态,那当然这个叫passive demwork啊,这个其实不是我们我们这节课会会会,具体事情的内容。
但是他很有意思的一点,就是他们其实还有另外一个视频啊,我临时没有找到,就是说他们其实是就是亮点是什么呢,就是说实际上这个角色,这个机器人在下坡这段时间,他是不需要任何额外的,比如电啊去驱动这个角色。
因为它完全就是靠重力自身的运动往前移动,所以时间他们后来有一个工作,就是说我可以在这上面加一点点驱动啊,让这个角色可以用非常非常少的能量,就一直往前走啊,他们那我记得当时那个那个视频。
就是他们让这个机器人在操场上走圈啊,可以走很多很多圈啊,但是其实我们只是用它来做一个例子,就是我们其实走路啊,除了我们z m p空之外呢,其实我们可以它本质上来说就是一个,我们可以放任它摔倒。
但是在摔倒之后,我们需要去合理的去规划我的这个脚步的位置,来实现这个进一步的呃,来保证我最后后面是能够平衡起来。
但在这个过程中,我们其实就是说还有接下来问题,就是说如果说我们在基于这样的模型的话,我们该怎么去规划我们的这个脚步的位置,那当然这里其实也有一些相关的这种简化模型,来帮助我们完成这件事情。
比如说啊常用的一种模型就是所谓的ip m模型,模型就是inverted pendulum,就是到了一版模型,那什么什么是到了100,就首先什么是摆啊,摆其实是说我们大家知道百中,那就是上面一根啊。
就是上面有个轴啊,有一个有一根杆或者一个线连下来,然后下面有个重物,那个重物就是会在这个轴啊,会被这个这个线或者或者这个轴限制,它在下面进行摆动啊,这是这是正版啊,就是正常的摆。
那倒立板呢其实是反过来啊,是说我们这个轴在底下,我们轴在底下,然后上面一个物体,那上面有物体呢,就是说比如这个物体开始有个初速度啊,比如说像这边有个初速度,那这个在这个初速的情况下呢。
这个物体会向这边移动,那同时呢这个物体本身又受重力的影响,这个重力其实在这个轴旋转轴上,这个中心会有一个力矩,那这个力力矩呢会阻碍这个物体啊,这个小球发生移动,那时间我们其实可以自己做简单的推导啊。
就是说在这样一个,如果说没有其他的外力的情况下呢,那这个c档就是我这个中心角啊,和这个物体当前的位置啊,其实有这样的一个关系啊,就是这个加速度,这个角的这个加速度,其实是跟我这个重力大小是相关的啊。
跟我的重力和这个杆的长度是相关的,那当然这个i p m通常来讲,我们就是很多时候我们是有更复杂,因为如果说只是这样一个杆的话,那它其实没有太大的意义,因为我摆上去结果就掉下来了,那就没有任何控制了。
但是我当所以时间很多,控制问题呢是所谓这个ip m sorry,就是这个就是inverted pgoron cart,i p i p c啊,应该叫这样一个东西,就是实际上就是除了这杆之外。
我们下面是一个小车的,所以时间很我们控制的是这个小车啊,他在上面,比如说这个这个物体,这个杆儿啊,这个重物比如向右边倾倒了,还有这样青岛趋势,那我这个小车就向右向左边,不好意思向左边倾倒。
那个小车就向左边快速移动一下,那就保持这个这个物体在上面,其实我觉得这可能就是,我相信我们以前这个打扫卫生啊,经常大家玩了一些游戏,就比如说把扫帚放在手指上啊,那可以让那个扫帚不会摔倒。
这本质上就是这样一个东西,当然这个i p m。
这个i p c是一个控制领域的一个,非常经典的问题啊,就是时间有很多控制的方法,能够实现一个非常稳定的这样的一个控制啊,就是比如说像这其实像比如说我想去做这种,比如说自由控制。
这其实是一个非常经典的一个问题啊,包括比如像这个这个强化学习啊,或者动态规划呢,其实都是经常会把这个东西作为一个,非常经典的一个一个一个模型来进行,来进行分析,但当这些东西可以有更复杂的。
比如说双倒立摆啊,脸上面两个杆,然后是三道理,反正就更加复杂一些,那当然我们讲道理板呢。
实际上我们是可以使用刀类板这样一个模型,来去规划啊,我们这个脚的落点啊,等会从而能吃能够让我这个角色往前移动啊,同时你要保持平衡,那当然这里其实也是这个同学里面,这个这边一个就是动画里边。
一个比较经典的工作啊,我个人觉得是比较经典的一个工作,就是2010年的就是generalized by porn control,它实际就是使用这样一个思路啊,使用倒立板来规划我的这个脚步的位置。
当然这个思路也非常简单,就是首先这个角色我们知道它有个中心啊,它有一个重心,然后这重心呢到支撑脚的连线啊,那其实构成了一个倒立板,就是我我相当这个我这个摆的这个重量,就是我这个角色的重量。
这个这个这个摆球的位置呢,就是我这个角色重心的位置,那这个摆这个轴的这个位置,其实就是我的角度,这个关节的位置判断,就是因为本质上来说,我在这个single stance的位置的时候。
我这个脚是不会动的,所以它其实差不多就是一个倒立摆的,这样一个状态,那接下来呢,首先我是需要把这个角色状态呢,映射到这样一个倒立的模型啊,这我只知道这个角色之心在哪里,知道他的脚在哪里。
我也知道这个知心的速度,因为人在向前移动了,然后呢他其实这个他提了一个思路呢,就是说我其实始终是希望我,因为我正常人正在摔倒嘛,比如我在向前走,我其实没有失去平衡之后,我需要摔倒。
那我其实速度会越来越大,那我希望去找到一个什么呢,我希望去找到我这个记一个角的落点,使得我当前这个角色他的质心啊,这构成了一个倒立板,他现在有个速度,他在这个角落点之后。
它会逐渐逐渐摆动到我这屋这个角的正上方,那我希望他能够在脚的正上方的时候,他刚好能把这个达到这个稳定的状态啊,就是达到速度有零的状态啊,就这样通过这样的方式的话,我可以控制我这个角色。
这个速度始终是在一个这样一个范围内,就是每次我都让他这个角色在最高点上得到零,然后再走下一步的时候,他会又下稍微稍微加速一下,然后又在下一步回到零啊,就像这样一个状态,那在这过程中呢。
实际上我们可以通过这个当前时刻,我执行的速度好,来计算出我下一步这个角应该放在哪里啊,使得这个构成的这个倒立摆能够实现,我转到摆到顶端的时候,它是速度是零,那我可以算出这个速度之后,这个位置之后呢。
那其实是我就可以从我角当前的位置,到这个目标位置,我们可以做一个轨迹,做一个插值,或者或者做一个啊样条,那它就是一个角的轨迹,那接下来呢有角的轨迹之后呢,我们其实就可以用i k啊。
通过这个质心的位置加上角的位置,那么可以算出一个目标姿态,然后又加上pd控制,我们就可以实现对这个角色的控制,那当然这个最主要的目标就是说,我们是希望能够找到一个点啊,找到一个下一个这个摆。
这个就是落地点啊,其实也就是我这个摆球的这个旋转,那个轴这个位置,那这该怎么算呢,其实也是非常简单的,因为本质上来说,如果说我们在某一时刻,这个这个球它的速度是v,然后呢。
这个球相对于比如我已经找到了一个位置,那这个球相当到这个位置之间,其实构成了一个一个倒立摆,那个摆摆摆的这个呃杆的长度是l,那接下来其实可以我们可以用动量守恒,动能守恒。
能量守恒就是这个摆它在往下摆动过程中,它其实是它的动能在逐渐不断的变化,转化成势能啊,如果说我们知道摆到最顶点的时候,它动能是零,那它势能其实是达到最大,然后这个它在这个高度其实刚好等于摆的长度。
那那这种,如果说在我们知道当前的这个速度的情况下,我们要知道未来的高度和速度,那我们其实可以知道这个杆的长度啊,应该是多少啊,进一步的我们可以知道这个杆儿相,相对于我当前这个点啊。
至今就未来这个这个这个这个嗯,大略版的这个轴点,相信我的知心啊,我需要移动多少距离,那把这个距离加上我的心,其实就是我的脚的位置,那这样的话我得到这个破烂之后,我们就可以做进一步后面的这样的一些操作。
那当然这个方法其实还是非常经典的,其实还是非常非常的这个通用的,或者非常的这个其实效果也是非常好的,就是首先他其实对很多角色都可以使用啊,就是我腿的长度可以变化,我是角色这个大小都可以变化啊。
那除此之外呢,其实他也是非常这个叫非常鲁棒的啊,就这个角色可以可以让上半身比会做很多动作。
我也可以去改变,比如说我可以让这个角色,比如说它互相碰撞。
那其实可以也会保持这个平衡,其实主要也是因为这个倒立板,它会实实时的根据我当前的这个状态啊,去规划我下一次的状态,那其实这样的话,不管我有什么,比如说像这个角色向左边推一下。
那其实它会自动改变他的脚的位置,去向左边去多移动一些,去保持了平衡啊,这是一种一种方法,除此之外呢,比如说我这个角色发生一些这个姿态的变化,或者让这个角色去推一些东西,或者拿一些东西。
其实都是可以通过这个方式来实现的,所以这是一种就是通过倒立板啊。
就是一个非常简单的一个简化模型,来实现步行的这样一个这样一个方法,那当然相对来说这个方法还是稍微复杂一点,因为主要是说虽然说我计算到了,用大维板来计算我的这个关节的位啊,落点的位置相对来说比较简啊。
不是太复杂,但是我们把这个位置,比如说我们转化成ak啊,转化成这个控制姿势,这一步其实其实是需要需要花一点功夫的,所以实际上还有一些更简单的方法啊。
这个是更加稍微早一点的工作啊,就是说叫sim卡啊,叫simple by pad log模式,很tro啊,这个是这个你康康老师07年的这个工作,应该说这个工作也是这个领域,非常经典的一份工作。
应该说而且是说什么呢,就是在这边工作,因为他是第一个实现了比较鲁棒的啊,这种步行控制的这样的一个工作啊,就是在这个决断化领域,可以通过一个非常简单的反馈,实现一个鲁邦的这个这个这个不行控制。
那当然我其实也建议大家有兴趣的话,可以读一读这啊这几篇工作,但这个东西是怎么实现呢,这个这个工作呢,就首先它其实是一个有点像我们上节课讲到的,比如说跟踪控制器基础之上我加一个反馈。
就回想一下上节课我们讲的内容,我们讲跟踪控制啊,不是就是我们讲开环控制,我们可以去优化一个控制,测控制轨迹啊,我用pd控制器去跟踪这个控制轨迹,它可以生成一段动作,但是呢这里有个问题。
就是如果说我在生成这个仿真过程中,如果说这个角色受到了一些扰动,除了一些扰动,那在扰动的情况下,如果说继续跟踪原来的开环的这个控制,控制轨迹的话,那它就会摔倒,因为开关控制的是不能根据我当前状态进行。
进行进行反馈的啊,我们需要一些反馈策略啊,非bank非ban policy,那所以说这个sim卡啊,它其实本质上就是前面这种方法的一个嗯,一个实例啊,一个一个一个特例,就是它其实包括两部分啊。
三部分或者是其实就是两副,就是第一部分,或者其实主要,其实本质上就是一个跟踪控制器啊,当然其实这个论这个方法原来刚提出的时候,它其实是用了一个啊状态机来实现,但其实本质上就是跟踪控制器。
它其实定义了四个不同的姿态,然后这个角色分别在这四个自动,四四个或若干个不同的姿态之间进行切换,就是我每次跟踪的目标,你pd control啊,pd控制器跟踪目标就是在这几个自带之间切换。
但实际上如果不是这个,我们完全可以用一段比如说运动轨迹啊,一段动捕数据来代替我的状态机,那其实本质上来说它就是这样一个开关控制,那这里除了除了这一点之外呢,其实这个sama其实提出了就使用了一些技巧啊。
就是说因为我们知道人保持平衡,其实很大程度上我们是需要保持上半身的,它需要处于一个竖直的状态啊,如果不是出状态的话,那其实很容易这个人就会就会摔倒,其实总体来说,数值状态是一个更加容易稳定状态。
所以说它实际上为了控制上半身的状态呢,其实它是通过啊两个大腿关节啊,大腿根的这个黑关节协作啊,加上这个腰部这个关节,这些关节协作,来实现对我这个整个上半身这样的一个控制,就是具体来说就是什么呢。
就是说我们认为上半身我的这个ta,对我的这个直躯干这个关节,我希望它的它使用保持数值,在这个全局位置上保持数值,那我们其实可以用pd控制来计算一个例,举这个例句,应该如果说这个例句加在我这个堡垒上的话。
那它是需要保持数值的,但是呢这个例句因为我们整体来说,我们这个合力矩就是整个物这个角色本身,它的竞合力矩应该是零啊,其实我们之前也讨论过这件事情,如果说不是零的话,那这个角色看起来就不真实。
就他而且他也是这个物理不准确的,因为从物理的角度讲来说,我每个力都会有一个反作用力,那这样的话其实会保证我的这个合理,举个例,所以实际上它是通过什么呢,就是说首先我通过保持水平啊,保持数值。
我可以计算一个上半身啊,就这个这个就直躯干这个关节它的力矩,然后呢另外一方面呢我这个摆动这条腿,摆动这条腿,我们会通过某一个目标转目标的旋转,加上pd控制,我也会算出一个例举。
这两个例句是我希望能够实现的,那这两个力矩,因为它它才我们是可以知道的嘛,那这两个力矩的和应该是跟另外一条腿的力矩,所以说如果说这两个力就算出来了,那这条腿的例句,其实我也可以直接通过一个。
就是他们三个求和等于零这样的一个方程,简单的方程可以求和求求出来,所以这样的话就是从就是从simon的这个方法里面,它其实第二步就是就是说,我可以通过就是这个计算来保证啊,我这个root啊。
就是躯干那个旋转啊,它能够这个处于一个水平的数值的状态,那第三部分其实也是最重要的部分,就是我们这个sa max就是质心的这个平衡啊,我们前面提到了,就是实际上我们后面这几种方法呢。
目标并不是说让我保持我的质心,在我的当前的这个support polyon有支撑面的上面,而是说我们是希望去估计下一个脚步的位置啊,能让这个脚步的位置能刚好让我的至今始终,它的移动始终处于一个可控的。
这样一个控制范围,所以sim卡其实使用了一个,非常简单的一个思路啊,就是说我们要控制至心,我们其实是相当于什么呢,是相当于我需要,大概是根据我当前至亲的速度啊,和当前最新的位置去计算,去估计一个。
下一次脚步需要落在哪里的这样一个状态,就前面我们用ipm其实也是同样的,只不过ip我们是使用了一个这个大力版,这个模型来进行这个估算,那如果说我们想再再简化,再偷点懒啊。
那我们其实可以进一步的就认为我我这个脚,比如说我这些向前倾倒的,比我往前摔了,那我肯定只卖多卖一点来保持平衡,其实大家可以想象就是大家凭生活中,生活中的经验是类似的,比如我脚被绊倒了。
那我其实正在向前跌倒,那我肯定是脚迈大一步一点才能保持,才能让我这个很容易恢复平衡,那如果说相对来说,比如说人有人有人向后推了我一把,那我其实我的之前的速度是更加小一点,那为了能保持平衡的话。
其实下一步呢会相对来说会往后收一点,甚至往后甚至向后退一步来保持平衡,所以实际上它有一个什么关系呢,就是说如果说向前的速度越大,那我其实这个脚啊向前移动的也要也要越快,摆动腿,那其实反相反的有类似的。
所以说这个速度啊,3d max的速度和位置其实跟我这个角的移动啊,就是我下一步落点其实有一些关系的,但这关系呢我其实很很可能很复杂啊,对我很难去分析出来,那为了能够实现这样一个控制了,我们可以解。
可以进一步的做一个非常非常大的一个简化,或者近似,我就认为我的这个3d max和sa啊,sa mass position,sa max of osty,他们两个跟我的脚向前摆动的速度,是呈一个线性关系。
可生成一个线性关系,那这个线性关系其实或者最近目来说,其实因为这是二维角色来说,它其实就是300万position,就是一个一维的一个量,vlose是是也是一个意味的量,所以实际上就是一个嗯。
就是两个参数加在一起的关系,那这个因为我们是希望,如我们比如说三代max向前摔倒的时候,我们是希望这个摆动腿能够尽可能地,快速地向前移动来去保持,我保证我能下一步能够及时落地,能够保持平衡。
那这种情况下呢,就是我我是根据我这个3d max position和velocity,乘上一些系数,目标的这个角度上,那大概是什么意思呢,就是说如果说我发现这两个比如速度过快了,速度过快了。
可能是我正在摔倒,那意味着我这个摆动腿需要摆得更快一点,那这样因为我们摆动腿是用pd控制来控制的,所以也就是说我这个摆动腿的目标的角度,应该再往上一点啊,就可以保证我这个g在pd控制情况下摆动更快。
如果因为本来我这个角色是在跟踪一个轨迹嘛,这样的一个速度和这个线性的这件事儿,这些速度和位置的一样一个线性关系啊,那当然这里其实有个这个基础的,就是我们这个参考的这个轨迹啊,就是我们当前的跟踪轨迹。
那后面的部分就是我们的非bug的这个反馈量,当然这是一个非常简单的策略,就是实际上你可以手动的去调这两个参数,找到一个组合适的参数,那这个参数可以让这个角色能够,比较稳定的走起来。
那这其实是当时这个非常有意思的例子例子呃,但是对二位角色其实来说,这两个参数还相对来说是比较容易,比较容易实现的,但是这个这里其实有一些例子,其实你可以看到我如果说我给让了一个角色。
这个二维角色去去跟踪不同的轨迹啊,加上一些这个相应的,这个我们的这个反馈的参数,因为这反馈参数其实对,其实跟前面的那个ipm不太一样,就这个这种线性反馈是更加简单,简单粗暴的一些方法,就是实践性很简单。
但是相对来说呢,它的这个啊反馈的这个鲁棒性相对弱一些啊,比如说实际上你相当于不同的动作,你需要专门去设置这样的反馈参数,但另一方面呢,就是说其实作为一个比较早期的工作,就是说这个他其实也能控制三位角色。
就是对三位角色来说,你前面这里这一条公式是,因为它代表的只是一个方向上的,这个这个这个这个旋转啊,对于三维来说,实际上我同时需要控制这个方向旋转,就向前移动和向侧面移动。
所以它其实会是两个这个单独的这个,反馈控制策略,那另外一方面就是说,其实作为一个非常简单的控制器呢,就是他这个动作质量上稍稍稍微稍微有一点,不是很尽如人意啊,因为看起来还是比较像一个。
像一个机器人的这样一个状态,但总的来说呢,通过这种这是一个非常简单的一个啊方法啊,能够实现一个这个比较稳定的这样的一个,这个步行控制,ok行,那我其实我们今天主要大概,就是讲了这样的一些内容。
那首先是我们要讲一下,这走路这么一个非常经典的例子啊,就是我们在过去就是在这个领域里边,我们是怎么去分析它,怎么去控制它的啊,特别是说我们基于减号模型的方法,其实简化模型这方面其实还有很多工作。
除了我们这里提这三个工作之外,还有一些其他的工作,能够实现相对来说更好的效果,但总体来说简化模型的思路呢,就是把一个角色啊,把他给,比如我就把他最重要的部分,跟觉得跟这个运动最终相关最高相关的部分。
比如说知心啊,比如说这个支撑脚的位置,这些信息拿出来构成一个简化模型,然后通过在这个简化模型上进行计算啊,进行规划,我们可以实现一个简化模型的,一个运动的估计啊,运动的这个计算。
然后呢再去根据这个简化模型的计算呢,我们再去还原到这个完整模型啊,让我们这个角色能够动起来,那这是这一些方法的思路,但是缺点是什么呢,就是缺点就是我们前面用的这些简化模型。
其实很多时候都是来自于我们大量的对走路,这么一个特定动作的一些分析啊,就是时间很多,这几套模型它是特化的,基本就只能做走路,如果说我们用它来做一些其他的动作啊,比如说做一个后空翻。
那其实你是没有一个相关相应的这样简化模型,能够让你很容易地实现,当然近年来我们也看到一些一些方法,就是很复杂的方法,比如说我可以通过ip来实现一些,比如像后宫番啊,或者像这种啊,像是侧手翻啊这些动作。
但总体来说这个是那个系统会非常非常复杂,就是这个时间起来更加困难一些,所以一个很大的问题,就是说我们该如何把这些控制啊,去泛化到更多的motion,或者说如果说对于其他的motion啊。
或者说对于这个更广泛的动作,我们该如何实现控制,其实这个实际上在深度学习或者深度强化学习,这个兴起之前呢,其实一旦这个我们就是,其实这个啊学界其实也没有特别好的方法。
我觉得大家其实还是从这个机器人控制这一方,这一类的方法来进行来进行设计,那如那在机器学习出现之后呢,其实我们可以发现很多时候,我们这个前面这个方法我们可以通过优化啊,可以通过学习强化学习啊。
通过各种各种设计来实现啊,就是我们只要我们给一些这个参考数据,或者给一些更更更确定的指标,那我们就可以训练啊,得到一些像相的控制策略,但是不管怎么样,虽然说我们后面这些方法,比如基于学习方法。
我们可以实现更复杂的控制,但是呢相对来说它的解释性也更差一点,就是说我们不太容易去很容很明,很轻松的去计算,比如这个角色他现在平衡,但他到底多平衡啊,它能承受多大力啊。
那这个其实对于我们这个基于学习的方法来说,通常是一个短板,但是对于前面就用这种比如z m p base的方法,或者是这种简化模型的方法,很多时候你是可以有具具啊,具体的这样的一个计算的。
就是我是可以大概算出来,这个角色当前它有多平衡啊,或者它可以承受多大的外力而不摔倒,那这个其实对机械类来说是更加就是很差异的,就是其实更加更加友好,不管怎么说,就是作为一种非常经典的方法。
我觉得也是非常,也是非常值得这个进一步的了解。
ok那我们以上就是我们今天的主要内容啊,也是非常感谢大家这个春晚的时间来,还是来参与我们今天的这个这个活动好,那现在参与我们今天的这个课程啊,我们就像刚才我说的,我们其实还有最后一次作业啊。
就是这个我们会在下周上课啊,这个我们之前我们今天我们会把它,这个发布在这个,还有发布在我们这个这个github上,然后也是希望大家能够,这个兴趣同学可以来进一步的挑战,那另外呢就是说下节课啊。
是我们这次这个整个game 305的最后一节课,当然其实主要内容会涉及到相对来说,比较多的一部分啊,就是涉及到这个嗯,就是会相对一些强化学习和自由控制的一些,就是基于摩恩啊。
其实模型的一些方法的一些知识,好的啊,那我们也是因为时间的关系啊,我们今天的课就到这里了,大家有什么问题呢,我们可以在微信群里边做进一步的讨论啊。
GAMES105-计算机角色动画基础 - P13:Lecture12 Optimal Control and Reinforcement Learning - GAMES-Webinar - BV1GG4y1p7fF
好的啊,那我们就开始上课了,也是非常感谢大家来参加我们这个games,105的最后一节课,是我们今天是首先从跟强化学习非常相关的啊,这么一个啊控制领域的一个一类技术,一类理论叫做最优化控制,从这出发。
然后来进一步来讲解一下我们这个强化学习啊,和这个一些传统的一些方法的,这样的一个一个啊一个区别,那就让我办公室的,实际上我们今天最首先是先讲一讲,关于这个自化控制的一些基本知识,因为最优化控制啊。
其实也是在我们这个决斗动画啊,就特别是基于物理的决动画发展过程中,其实也是有相当的一些比较好的工作,是基于这类方法的,那我们其实后面也会介绍一些关于这个啊,还有就是通过优化的方法啊。
来得到一个比较简单的这样一个控制策略的,这样的一类一类工作,然后最后呢,我们其实回顾一下,这个强化学习的一些基本知识啊,当然我们可能无法去准啊精准确的去啊,去比较细节的描述。
想要就去的一些算法的一些细节啊,当然我们只是大概的给大家提啊,提一些这种啊概念啊,或者方法呀,一些关键字啊,如果大家有兴趣的话呢,可以在后面的这个,在这个我们的这个课后的其他时间呢。
可以自己去去去了解一下,ok那我们其实回顾一下,其实我们前两节前面几节课不停的在讲控制啊,从开环的控制讲到闭环的控制,讲到我们用简化模型来实现一些对这种比较啊,基础的这种运动,比如说这种原地走啊。
走路啊,这其实是一个非常经典的,也是非常基础的这种这种运动形式,来对他们实现一个控制,那其实我们这里回顾一下啊,其实我们前面讲这个我们实现一个,我们如何去实现一个控制。
我们只能是通过在这个角色身体上施加力啊,实力和力矩其实主要是关节力矩,然后来实现这个对这个角色的这个驱动,那当然这个过程中我们如何来去计算这个例句,一方面一种方法是说,我们其实比如说我就想做一个动作啊。
比如我一个轨迹,我有一个这个一个后空翻啊,我想做一个后空翻,那么我希望去自动去找到一系列的这种控制的,这种策略,一般来说可能是一个pd的target,然后呢我去执行这个pk target。
他可以去让我的仿真的这个轨迹啊,跟我的这个运动轨迹是相同的,那我们其实前面讲到了,为了能够找到这一系列的轨迹,我们其实是可以把这个控制,把它给啊建模成一个优化问题,那这个优化问题实际上我就是在每一帧啊。
每每仿真一步,我都可以计算一下,当前这一步和我的这个参考运动数据的偏差,那这个偏差啊按照这个仿真步长,按照这个轨迹的长度把它加起来,那就构成了一个优化问题,优化的对象是什么呢。
优化的对象呢其实就是我每一步的这个啊,所金世佳这个力,那当然这里其实有一个非常重要的一个问题,就是优化的时候,我们需要去满足我们当前的物理规律,那对于我们来说,其实在仿真里面它并不是真的物理规律啊。
它其实是物理规律的一个简化,但它本质上还是一个物理规律,那其实我们那这个固定规律本本身呢,我们可以把它写简啊,简单的写成抽象的,写成这么一个一个函数的形式,那当我们前面这几节课其实也介绍过。
其实如果是一个刚体的仿真的话,那我们其实可以通过一系列的这种带约束的啊,这样一个方程来进行进行进行描述,那另外一方面呢我们前面也提到了关于feedback,就是前面如果说我们只是优化轨迹的话。
那他其实拿到的是一个开环控制啊,或者是叫这个前馈控制,其实开环控制跟前后控制,还是从细节上来还是有一点点区别的,就是开环控制之说,我完全不在乎我的这个输入的变化,我就只是单纯的在执行我的控制。
但前馈控制呢其实稍稍有一点点的改变,就是说比如说我这个加了一个扰动,我这个状态加了一个扰动,那这个扰动肯定会带来我这个角色这个状态啊,发生这个一定变化,如果说我们直接去执行这个,前这个开放控制的话。
那他其实也会直接去,由于你原来的这个执行的目标,其实已经变化掉了,那前馈控制呢其实稍微多一点点啊,前馈控制其实理论来说是,它是会根据我的production啊,根据我的这个扰动来改变一点点。
我的那个开关控制的那个控制器,但是实际上呢因为它是基于这个prevation的,就是他其实并没有去根据我的状态的改变,而改变,所以说其实本质它所带来的变化,我们的这个这个角色本身的变化。
当然我们前面其实是把这两个,把这两种就是开环控制和乾坤控制,把它混在一起去去描述,但实际上他们相当于,他们是不根据状态本身来进行改变的,但他其实还是根据一些预定义的一些一些策略。
去进行进行这个进行这个控制信号的修改,那我们前面这个为了能够去尽可能的去解决这,个啊扰动带来的问题,那我们其实还是需要引入所谓的反馈策略,那这个反馈策略呢,他就根据我们当前角色受到扰动之后的。
这样一个状态,他去去更新啊,实时的去更新我的这个控制的策略的变化啊,控制信号的变化,从而保证我在整个运行过程中,不管我是怎么去对这个角色啊,对我们控制的对象进行干扰。
那他这个控制对象总是能够保持这样一个动作,那当然这个开关控制啊,就是闭塞,这个反馈控制,其实也是可以描述成这样的一个优化问题,那唯一的跟前面那个轨迹优化,其实是呃形式是非常像的。
那唯一的区别呢就是说轨迹优化里边,我优化的是每一个时刻啊,所对应的这个这样一个啊控制信号,但是对于这样反馈控制来说呢,实际上优化呢是这样的一个控制策略啊,控制策略本身,那这个控制策略。
它其实是一项可以认为是一个函数,那这个函数根据我当前角色的状态,来计算一个这个控制信号,所以实际上这两种方式啊,不管是轨迹优化还是我们的这种闭环控制,这种优化啊,其实他们统计来说。
我们都是属于这种最优化控制的,几个不同的这种类型啊,其中一种类型就是前面所说的这种轨迹优化啊,或者我们叫开环控制,它的一个更加准确的定义,就是说当我们给出一个起始状态,然后呢我给出一个目标状态。
那我需要去根据这个起始状态,就直接计算出一个轨迹啊,一个控制信号的轨迹,那沿着这个控制信号轨迹进行执行的话,那我就可以从一个点起始点到目标点,那当然这个好处是什么呢,就是说我只需要计算控制信号。
相对来说这个问题是比较简单的,那坏处呢就是肯定是,如果说这轨迹中间受到任何扰动,那很大概率的话他就无法继续执行,他会离开离开这个目标点越来越远,那另外的反馈控制呢实际上是计算了是一系列。
有点像计算了一个厂啊,就是我在对空间里每一个状态,空间里,每一个状态我都会有一个相应的控制信号,那这个控制效,总体上会把我不管从哪个状态开始,它会逐渐的把我推到我的目标状态身上,那当然想象一下。
这个问题,肯定是比前面这种开关控制要难一点的,因为理论因为你需要考虑空间里边所有的状态,这种状这个这样一个情况,所以这是其实是两种不同的这样一个问题,那当然就是左边问题其实是主要是这种啊。
这个这种轨迹化,那六边呢其实我们讲的,其实我们讲这个最优控制,其实大部分情况是处理的右边这种情况,而右边这种情况,它的理论基础呢其实是来自于这个dynamic program。
就是这个这个动态规划的这样算法,那当然大家可能学过编程或者刷过题的同学,大概是对这个这个词是非常不陌生的啊,这个动态规划啊应该是一类算法题,还是挺常用的一个算法题,那大家回答我们前面这个问题。
就说我们其实主要是为了去求解,这样一个优化问题啊,我们可以先看一下这个简单版的就是鬼泣优化,那这个问题该怎么去求解,我们前面其实铁蛋非常简单啊,我们这今天会稍微再多讲一讲,就这个问题这个该去怎么去。
怎么去怎么去这个啊分析这样一个问题,那当然这里其实我们要不得不先提到一件事情,因为这是一个有约束的优化问题,就说我是要优化这样一个函数,同时呢我有一个约束,那当然这里我们为了简单起见。
我们只考虑这样的一个等式约束的一个情况,那在有约束的一个优化问题,其实是一个一大类啊,我们这个非常常就是常见的优化问题中的一类,比如普通的优化问题,如果说没有约束,没有约束。
我们想想我们i k其实ik的问题的话题很多,也是有约束的,只不过我们在讲ik的时候,没有提约束这件事情而已,如果没有i没有约束的话,那么其实一个优化问题,我们可以通过一些比如说梯度下降的方法。
去找他的解啊,虽然说只能找到一个局部最优解,也就是说我计算出f啊这样一个优化目标,它的梯度梯度代表了这个函数值啊,下升至那个增长最快的方法啊,方向那就是你沿着那个相反的方向去移动。
那你其实就会越来越小了,所以说这是一个梯度下降的方法,但如果说我们有个约束,这个约束会带来什么,带来什么不同呢,就是说比如说我们这个函数本身啊,我们简单画一个函数。
比如说这个fx就是一个二维平面上定义的一个,比如说这个圆周啊,就是fx啊,sfx y我们可以写,比如说x平方加y平方,那它其实它的值就是这个与这个每一,每一点的值啊,就是这个点到原点的距离。
所以这个函数的这个曲线画出来,大概是这个样子,一圈啊,大概就这种一圈一圈一圈一圈上来的,这种这种函数,那另外一个函数,那这个g啊它是一个约束,那约束其实在r平面上会呈现出什么呢。
一般来说我们比如说它比如说它是一个啊,就是一个一个一个算一个方程,那它其实应该是二,对应二维形平面上的一个曲线啊,构成这样一个曲线,那在这个过程中呢,其实我们目标是站在这个曲线上啊,这个约束的意思代表。
我们这个解必须在这个曲线上,所以实际上我是要找这个曲线上的点,使得fx最小啊,这是我们这个带优化的约束目标,当然这个问题我们现在提到了,其实有约束的问题不好解,那我们其实可以把它转成一个硬约束啊。
转化成一个软约束,那软约束意思就是什么呢,就是说我其实可以把g啊加上一个系数,然后加到我们的这个优化目标里面去,那这个时候如果说我从这个优化到最优的时候,那其实一方面fx本身要很小。
另一方面gx也要很小,但是因为js等于零嘛,所以说也说他他虽然可能不在这个线上,但是也离这根线不是很远,那当然确实一方面他还是那个问题,变得好解一点,因为没有约束了,另一方面呢就是说解的啊。
他这个问题的解跟原来那个问题解释不一样的,它可能会他的最优解有可能是不满足,不在这条线上啊,刚才我们说他其实有可能是在这线附近,那我们其实还是希望,如果说我们不用这种soft concern方法。
我们还是希望能够去直接去保证,我这个解是有的,只是在这个曲线上的,我们该怎么办呢,那其实这个过程中我们其实也是可以看一下啊,就说分析一下,因为这个比如像这个特例,这个f x它总是越往里越近。
圆点这个值越小,然后呢,我这个点我所能够满足约束的点,一直是在这条直线上啊,在这条曲线上,所以说我们可以知道这个曲线,如果它越沿着曲线越接近我这个圆圆心,那肯定它的这个f的值,就这目标函数的值就会越小。
那我们其实可以计算一下,就是说实际上目标函数的值,如果说我对目标函数做做一下梯度,那其实每个点空间里,每个点这个目标函数的梯度方向,其实都是指向啊,或者梯度的反方向,都是指向它那个值下降最快的方向。
然后呢,他这个如果说是沿着这个嗯约束上进行移动,我们发现如果说因为我移动的时候的速度,始终是沿着这个约束的这个曲线的切线方向,也就是说如果说这个切线方向呢,跟我这个当前这个点。
就是f的这个gradient的方向是夹角,是小于90度的,那就说明我接下来这个移动的方向,是跟我这个f下降的方向是相同的,所以它会这样的话呢,我你随着我的移动,那f的值会逐渐变小,一直移动到什么时候呢。
一直移动到这个切线的方向,跟我这个f的梯度方向是垂直的时候,那这个时候呢我这个只要我不管怎么移动啊,它都不会改变f的值,如果说我继续移动的话,那可能这个这个切线方向跟f方向相反了,那我就越移动。
这个f2 要变大,那其实就也就是说,其实我的极值点是出现在什么情况呢,是出现在这个切线啊,跟这个f是垂直的这样一个情况,那时间切线垂直,但这对于二维进二维的情况来说,它是一个切线,那对于三维的情况。
那可能就是一个切面了,那这种情况其实等价于说什么等价,于是说我这个g作为一个函数,它的梯度的方向,其实他梯度方向肯定是,我跟我切线方向是垂直的,他跟这个垂直,它跟那个也是垂直,所以时间等价于说什么等价。
就说如果说x是这个整个这样一个,优化问题的啊,带约束优化问题的一个极值点,那它肯定能够保证什么呢,这个f也就是我们的优化目标,在这个点的导数方向跟我们的这个约束啊,约束函数在这个点的导数方向啊。
他俩应该是平行的,其实是说就是因为是这个方向的切线方向,跟他跟那个f的导数垂直,而切线方向又跟这个g本身的导数是垂直,那实际上最后导你可以推导出这两个东西,他俩是平行的,当平行呢意味着他俩是共线的啊。
平行就是共线的,那其实也意味着什么呢,意味着fx和gx啊,他俩有这样的一个关系啊,就是我们可总是可以找到一个一个一个标量啊,一个数这个数呢乘上gx的导数,这是这个js导数的方向啊,把它成了一个系数。
那它可以得到f x的方向,这是我们共线的一个基本定义,所以这个其实就带来了什么呢,就是从这样的一个关系呢,我们可以得到一个这个,所谓的拉格朗日乘子法啊,当然这个条件本身是一个必要条件,不是充分条件。
也就是说只有说x是最优点的时候,它能满足这样的条件,但是反过来满足这样条件时候,f不一定是最优点,它有可能是一个局部最优,或者是一个暗点啊等等,这个这个问题会比较复杂,但是不管怎么样。
从这个地方我们可以得到一个,就是拉格朗日乘子法,其实大概是可以解释成这样的一个方式,就是说比如说我我的优化了,这个得到极值点的一个条件,就是说我的两个函数啊,f和g它的导数是这样一个这样一个。
贡献的一个状态,那我们其实可以定义一个拉格朗日函数,那这个拉格朗日函数呢,是首先是包括了我的这个目标函数,还是然后呢加上一个lambda啊,作为一个拉格朗日橙子,他其实对应的差不多就是这个狼的。
就是说大概是我贡献之后呢,他们俩的这个这个标量差变量系数,然后呢lambda乘以g啊,加在一起构成一个拉格朗日函数,当然有这样的定义之后呢,其实我们可以直接把这样的一个优化的,这样的一个条件啊。
把它转化成导数啊,就是实践,我发现如果对这样的一个,如果说我们拉拉还是直接是这样定义的,那么对拉杆式函数l去进行求导,对x求导,那其实可以得到这样一个公式,它其实就是前面我们的这个这个平行的。
这样的一个条件,那同样的同时如果说我们对lada进行求导的话,它会得到g啊,就是这个原来的这个原来的这个这个这个啊,约束约束函数,然后如也就说让在这种情况下,让这个拉格朗日函数取得极值的x和ld。
就刚好能够,特别是那个x,就是使得原来这个优化问题,取得极值的那个x啊,这其实是因为本身,因为本质上是来自于这个优化的这个条件,我们其实把它对应到拉格朗日函数,拉格朗日乘子法这样的一个条件。
也就是我们前面说的第一行啊,这是一个平行于g的这样的一个啊最有条件啊,另外一个就是说我们这个第二行,其实对la进行求导,其实得到的是gx,就是我们原来的这个这个约束约束函数,那这个其实就是啊。
我们在求解一个等式约束的优化问题的时候,常用的一类方法啊,拉格朗日乘子法,那当然如果说其实我们前面提到了,因为比如说我们在建模这个运动方程的时候,这个摩擦啊不是那个那个支持力和摩擦力。
这两个通常来讲不是一个等式约束,而是一个不等式约束,那这种情况下,其实拉格朗日乘子法就会变成了kkd条件了,那个其实会更加复杂一点,我们这里就不再多介绍,那其实回到我们前面这个轨迹啊,轨迹优化问题。
这是我们的优化目标啊,这优化目标函数,它是一个沿沿着时间进行积累的啊,其实理论来说,如果说我们是一个连续时间的问题的话,那这里其实应该是一个积分,当然我们这里其实这个因为我们前面提到,在仿真里边。
我们通常会把它离散化,所以这里其实是一个就是一个求和号啊,但是本质上这俩是嗯嗯是非常有相关性的,然后呢,我们其实有有,我们前面提到的这样的一个运动方程啊,作为它的约束,那这两个就是一个优带。
有约束的一个优化问题啊,那我们其实可以很容易地写出它的,拉格朗日方程啊,其实就是上面这一行加上lambda的转置,乘以下面这行啊,这就是拉格朗日方程,看着比较复杂,但其实跟前面这个是一样的。
一样的一个一个一个结构,当然在这种情况下呢,其实我们前面提到了就是拉格朗日方程,它的极值点,也就是分别对x和拉姆达分区去求导,然后让这个求导数等于零得到的那个解啊,其实就是原函数那个解。
所以说我们写出拉格朗日方程之后呢,我们可以计算出他对于这里每一项啊,这是哪一项呢,比如说因为我这个轨迹我优化的目标是轨迹,以及我的这个action啊,以及我的这个这个控制信号的这样的轨迹。
所以说实际上我要求导数的时候,我需要对里面每一个变量啊,包括了所有的轨迹里,每个状态以及轨迹里,每个这个action就是我们的这个控制信号,然后以及对lambda进行求导,那这个求导过程稍微看起来有点。
但实际上因为这个求和号,你会发现它其实只跟当前时刻,t时刻和t加和t加一时刻相关,那其实它只会有两项啊,就是主要就是当前当前时刻的这一项,和他上一个时刻那一项,所以说其实求导过程也是相对来说比较简单的。
它会大概得得到这些性质啊,首先对x t求导,后面这项求和是没有的,因为它是s t是最后一个啊,当然对蓝t是有,然后对对前面的这个每一,中间的每一时刻进行求导,它会多出一点,多出一项。
然后对a求导有这样的公式,然后对拉姆达求导,其实就是原来的运动学方程啊,这个其实是可以表明验证的,那这样的情况下呢,实际上我们可以把下面这些求导得到的功,得到的积分啊。
这个因为本质因为我们需要求最优解嘛,我们肯定是需要让他这个拉格朗日方程,对每一部分的导数等于零,那我们其实可以把右边这个做一下,稍微整理哈,把可以相当于把我们需要求的这些变量,给求出来。
那我会得到一些什么禁止呢,首先最下面这一行啊,他就是我们其实把这个s t r e,挪挪到左边去啊,挪挪到右边去,然后换个位置,那其实得到了这样的一个公式,那其实这个就是我们的运动学方程啊。
他根据当前的时刻的状态加上控制信号,计算下一时刻的状态,那上面这一项呢其实可以也可以直接写出来,我们可以得到lambda的最后一项啊,就就这个轨迹结束的时候,它的值啊应该是h,这是什么。
这是我们那个优化目标函数的每一时刻,里边的一个子项等于它的导数,对x的导数,我这里其实简写了一下,就是把这个d h d s写成hp s,这个其实是一个简写,然后呢这个对应的lambda t。
当我们算出最后一帧的t的时候,实际上我们可以用最后一帧从后往前去迭代,去计算前一帧的拉姆达提,因为你看这里,拉姆达t其实是一个递归递推公式啊,就是首先这个h这部分,我们其实求导可以算出来。
然后拉姆达t减1t加一啊,y s首先lt lt的最后一项就是lg的大t啊,它是一致的,所以说luna大t减一的话,可以用这个递推公式算出来,然后呢再往前推进,机器就可以不断的调用这个dj公式。
进行进行求进行求解,所以然后这两个landa啊,其实通常我们也会把它有另外一个名字,叫做cost state啊,就是他其实表现上有点像一个state,就是比如说正常来讲,我们这个状态在控制信号过程中。
不断向前去改变啊,就是一个正常的仿真过程,那这个ladder其实是有点像反逆向的过程,我其实在做一个逆向的仿真,然后最后一个公式,这个公式是稍微复杂一点,就是你可以看到,其实为了能够找到l的极值点啊。
他对a求导之后是这样的一个公式,那这个公式里边其实你可以看到前面这一项,我对a的求了一个偏导,后面这一项呢我也对a求了一个编导,如果说我认为我认为这个h,h是这个a的函数啊,后面这个f也是a。
它就是在我确定在s t是确定的情况下,那我们其实这可以看作是a的函数,然后f可以也可以看作是a的函数,那所以这一项呢其实有点像什么呢,有点像是说如果把这个我把h加上f啊,整体看作一个a的一个函数。
那这个函数我认为它是一个优化函数,我就求它的极小值,那为了求它的极小值呢,我肯定是需要计算它的导数,那它的导数其实刚好是等于这边的右边的部分,所以实际上是什么意思呢,就是说实际上这一行所代表的这个。
为了能求从这一行里求解出a来,我们本质上来说是可以认为,我们是在做一个优化问题啊,其实求解的是这样的一个优化问题,优化对象呢就是h的导数和f的导数,我们把它认为是a的函数,就是我认为xx是不变的啊。
它是一个a的函数,那当整个这个过程呢我们可以把它整理一下,就是右边这四个条件啊,右边这四个条件,但是我们通常来讲会把它稍微转化,变化一下顺序,那第一项啊,是我们这个运动这个状态的运动方程啊。
系统了这个动力学方程,然后中间这一项呢其实是我们的cost state啊,就是这个lambda的运动学方程,然后最后一项呢是我们去计算啊,去根据landa去计算a啊,就是我们最终优化的目标的这样的。
一个一个一个一个求解问题,那当然这一切这几个这些项目合在一起啊,其实是一个叫做庞特里亚金最大化原理的,这么一个或者叫pmp啊这么一个公式啊,就是其实是应该是说在最优化问题,最优控制理论理理论里边。
我们在解决这个开环控制的时候啊,开环控制的那个控制是最优的,这样一个必要条件啊,其实就是个p m p的这样一个条件,那他是这个彭德里亚金啊,一个俄俄国的科科学家,数学家啊,提出的这么一个这么一套理论。
那当然这个很老了,所以这个最早是为了大家,是为了研究这个火箭的这个控制,然后来发出了啊,这开发了这么一套理论,那当然其实相对来说呢,也是对于一些比较简单的系统来说,还是比较方便的一个分析的一个工具。
那当然对于这个p m p啊,其实就是一个非常就是所谓的shooting method,就是可以去求解p m p啊,就是用利用p m p来实现,对轨迹的这样一个优化。
那其实这个过程就是一个前向过程和两个反啊,和一个后向过程加上一个更新的过程,就像我们前面说的,首先为了能够去计算,因为目标来说,我们是不断的去优化我们的a,最终是我的轨迹能够满足从这出发到这结束。
那所以说我可以去有,但我一开始不知道我怎么用啊,我应该取什么值的时候,那我可以有一个某种某种方式的一个估计啊,猜测我就先猜测出我要执行一系列的a,那当然执行了之后,他肯定离我的目标比较远了。
然后目标但是这个但目标我可以先执行一遍,这样的a那执行过程中呢,我可以记录每一次执行a得到的那个状态,就a啊,从s0 这个发直线a0 得到s一啊,类似的得到s2 ,s3 ,我可以记录下来,那这样的话。
其实这个执行的过程,实际就是调用这个前下方程函数啊,进行不断的这个计算,那接下来有一个后向的过程,那其实就是用我记录下来的,这样的s和a来调用,我们这个cos state的这样一个方程啊。
从最后一帧先计算兰姆达t,然后依次往前去调用,然后回到s0 啊,其实就得到了对应每一个状态下的兰达,那其实是一个后降过程,其实这个有点像那个像那个链式法则啊,就是我们求解这样一个这个啊。
神经网络的时候啊,所需要这样一个都用了这么一个东西,那最后呢我们得到了所有lava t和s t之后呢,我们其实就可以去用这样的去去求解,这样的优化问题,那当然实际这个优化问题。
我们通常来讲不用去找到它的最优解,我们只需要计算一下它的这个梯度,然后用这个梯度更新一下t就完成了一步迭代,那实际上我们这时也不断的迭代,才能找到最优解,这是一个非常简单的一个,一个这个轨迹优化的方法。
那当然我们前面提到了,就是对于这个优化拍这个最优控制里边啊,当我们去需要去求解这样一个,最开环控制的时候,那我们其实可以就是它达到最优点啊,其实对应的就是这个庞特里亚金的最大化,最大公式啊,最大化原理。
然后呢前面我们提到这个shooting method的啊,他其实是这个p m p就这个帕拉利亚啊,maximum principle的一个直接应用,当然缺点是什么呢,就是实际上这个分析啊。
其实它首先要求呢就是它本质上来说,这个跟我们前面提到的这种优化的这个啊,对于复杂问题的这个优化,目标函数的这个这个性质也有关,那就是我们前面,如果我们前面在讲到这个这个轨迹优化的时候。
我们当时有几个图片啊,就是给大家看了一下,特别是比如说对于一个人走路或者跑步,这样的一个优化,他的这个目标函数是非常非常差的,就是它会有很大量的这种局部极值点啊,它会让我们这个优化变得非常难,非常难做。
而这个shooting method其实也是有这样的问题,就是说对于这种复杂的函数,它通来说表现是比较差的啊,所以通常来讲,它也是需要去根据一些其他的方法。
比如说像这种collocation method啊,像这种multiple shooting啊,这些技术来进行回合合在一起来进行使用,或者呢其实我们可以把它作为一个分析的方式。
但实际上真正我们做优化的时候呢,其实还是很多时候我们是需要用这种啊这种啊,比如梯度dirty free的这种方法来进行优化,ok那前面这里其实是一个开环控制的,一个一个一个理论上的一个一个分析。
那对于闭环控制,我们闭环控制我们前面提到,其实我们目标是什么,我目标是对于任何找到这么一个策略啊,派它能够对任意一个state啊,可能也许可以加上一个t作为这个输入,能够去计算一个合适os。
一个合适的这个action,一个控制信号,它能够让我最终达到我的目标,那这是我其实这样一个一个闭环控制的,这样一个优化问题,那当然在这个过程中,就我们可以从一些非常简单的一个例子来进行。
进行进行考虑这件事情,这个其实是一个非常经典的这个算法题啊,就是所谓的这个最近最短路问题啊,就是我从一个我有这么一个图,这个图上可能两个节点之间有些方向,有个方向的路径,这个路径呢有各自的代价。
比如可能是距离这样的一个函数,然后呢我们总是希望能够从一个点出发,我们希望能够找到一个最短的路径,到达另外一个点,这是一个非常经典的一个最短路径的,最短路径的问题,当然这个问题其实有很多种不同的解法。
就是一类方法,就是所谓这个动态规划的方法,那当然这个问题本身呢,我们其实他从数学描述来说,其实我就是希望能够找到这样一个路径,它就是一系列状态的这样一个轨迹,那这个轨迹上我可以把路径任何两个轨迹之间。
这个这个编啊,它的这个代价定义为一个一个优化目标函数,然后我们最终的优化目标,其实就是找到一系列这个这样一个轨迹啊,它能够使我的这个总的边的长度啊,边上的这个这个代价最小,那其实另外一个角度。
我们其实也可以认为,这个比如说从这个点这样一个状态,这个状态出发,它可以选择沿着三个不同的方向去移动,因为它有三个出点,那我们可以认为这三个不同的方向呢,对应的是三个不同的控制信号。
那所以实际上我们前面那个优化问题呢,我们也可以认为是什么呢,就是说我需要去找一系列的这个控制信号啊,它能够使得我靠前面那个最优化问题,使得最他妈这个最小化,那同时当然这个控制信号呢。
它会带来一个我们的这个运动方程的,比如说这个运动方程,就是说根据当前的这个状态,加上我的控制信号,我可以得到下一时刻的状态,就是因为我比如说在这个状态下,我选择了a2 。
那我自然我下意识就是就是s t r e啊,这样一个空这样一个位置,那再进一步呢,我们前面讲的反馈控制,实际上我们目标是找到这么一个控,一组控制策略,这个控制策略是说,我不管我从哪一个state的出发啊。
我们当然可以简化一下,我们可以认为这里t是不在里边的,就是我只考虑值,它跟s直接相关,而不考虑我时间这样的一个关系,他这个空中目标,就是说我可以从这个图里面的任何一个状态啊,任何一个位置,任何一个词呃。
这个节点我可以自动地计算出,我该去执行哪一个边,可以使得我沿着这个一支烟,一直不停的执行这个控制信号,它能够得达到目标,同时我的这个总的这个值是基本的小,那这其实是我们的这样一个最短路问题。
下面的这样一个控制策略问题,那在这里边其实会有一个非常重要的一个,这个这个必要条件啊,就说什么情况下我这个策略才是最优策略,那这个其实就是这个bman啊。
principle of optimioptimality,就是这个啊贝尔曼的这样的一个自由控制,一个一个就针对于控制策略,而不是前面提到的这个控制的轨迹啊,绝对控制策略的这样的一个最优的条件。
那这个条件是怎么说的呢,就是如果说这个派他是我,他是一个策略,如果说他是在这样一个问题上的一个最优策略,它会有一个性质,这个性质是什么呢,就是说我不管我从这个图里边哪一个状态开始,我不管在这个状态下。
我执行了哪一个action啊,一个运动难以控制,他都他会他肯定会到一个新的状态,然后在这个新的状态下,我可以不断地执行这个派,那他最终可以达到达到我的目标,然后同时呢通过执行这个派得到的这个轨迹。
刚好是从这个把这个状态作为初始状态,能够找到的最短路的这个最短啊,就是能够找到那个最短路啊,这是这个这样一个有用,这样一个啊优化的一个一个条件啊,就是这个取得最是这个派是取得最优化的,这样一个条件。
那当然时间这个也跟问题相关,就是有些问题可能是有没有这样的条件,有这样的,有这样就能够满足这样条件的问题呢,我们可以认为我们可以有一种描述,就是说这个问题是有这种optimal。
substructure啊,这个其实也是那个dynamic program,就是我们这动态规划能够成立的那些问题,所具有的性质啊,其实这两个差不多是同样的东西。
就是说什么叫optive subject structure呢,其实就是说我从任何一点出发,我就是如果说这个点啊,他在我的某一个的这个最优的轨迹上,那他肯定是从这出发到达最终点。
得到那个轨迹肯定也是最优的,那当然从这个bman这个自由化定理啊,自由化原则,我们其实可以得到一个可以定义一个函数啊,那这个函数叫什么,这个函数叫value function啊。
或者叫value state,它是可以在每一个状态下去计算一个值,那这个值代表什么呢,这个值代表的是从这个点出发,从这个节点出发,到我的目标所经历的所有轨迹里边,最短的或者最优的那条轨迹啊,它所的代价。
它所那个得到的那个代价的值,或者另外一个角度讲说,如果说这个派是一个最优的策略,那么这个v就代表什么,代表是从这个节点出发,他不断的执行派得到了一条轨迹,那这条轨迹上所有的这边的这个代价的和。
那其实就是这个点的这个v value的值,那这是value function,不好意思,那是什么,value function,很重要的就value function会告诉我什么呢。
比如说我想计算从s0 出发,我需要在这个时刻去计算我该选哪一个action,如果说我们已经有了value function了,比如说而且我们知道比如说在这个节点上,这个状态的one 6是30。
就是说明从这个节点后面,可能不知道有什么轨迹,它会到达目标,然后整体的这个最优的,最小的这样一个代价是30,然后呢这个节点是25,那这个节点是22,然后从s0 出发呢。
分别到这三个节点的代价是51和12,那我们可以直接得到一个什么结论呢,就可以直接得到,我们只要计算一下这边的代价,加上这个点的value function,那他得到的值就是说我从这出发沿这条轨迹走。
我能达到最小的一个值,所以实际上呢我们可以直接得到,从这个结论来说,我们可以给他从s0 出发,想要得到目标,最快的达到目标啊,或者说我是16的优化函数最小,那么就肯定是我可以直接去得到。
我只要执行这一条啊,沿着这条轨迹走,或者执行这个action就可以得到了,比如说再进一步的时候,就说如果说有质量value function,那么我们在这个时刻选择action。
就只需要计算一下每一个action加上下一节课的value,function的值,然后这个值最小的时候对应的那个action,就是就是我想要选择选择的action,那这样通过这样方式去解。
去选择action的这样的一个策略,那对应的就是我的最优策略,ok那其实回到刚才那个问题啊,就是还是回到这个盾最短的问题,但是我们其实只用它来做一个例子,我们的目标啊。
其实是就是在这样一个最短路问题里边,其实我同样的可以定义一个value function,那这个value function实际上是会对每一个节点有一个值,每个值,那这个值呢就分别是从这个节点出发。
到目标节点所需要经历的最短路啊,的这个长度就是这个这个value function,那实际上这个方式呢,我们可以稍微把它变形一下,因为其实是这是我需要对后面每一个系列啊。
就是得到一系列的这个action的去求最小值,那我们其实可以把这一系列action把它拆开,我们可以写成,比如说这个对于第一个action求最小值,然后里边是对剩下的action啊求最小值。
就注意下标从一开始和下标从零开始,我可以写成这样的一个形式,我可以证明它其实是两个等价的,那接下来呢我们其实可以看到,就是原来这个vs的定义啊,是这样子写的,然后后面这个如果说我这样把它展开一些。
他们发现后面这一半的这个定义,跟这个原来这个定义其实是很相似的,所以时间确实他俩是相是等价的呃,所以是同一个东西,只不过就是说后面这个action,我们可以把它写成一个value function。
在s一就是新的这个位置进行计算啊,得到了这个完了完了function的值,所以实际上我们这个value function本身就是相邻两针的,value function,它其实是有这样的一个关系。
那这个关系呢就叫做这个bincreation,就是说如果说我有一个最优的策略啊,最优的策略在这个最优策略下,我得到了每一个点,它的value function,然后这个value function。
它其实肯定是一定是满足一个这种迭代的公式,那这个迭代公式就是说我从一个状态,任何一个状态出发,他这个任何一个状态的value function,等于我沿着某一个action进行执行一步啊。
首先这action本身带来一个带了一个object,带了一个loss,带了一个cost,带来一个代价,然后呢沿着这个action移动到下一个状态,就是通过这个运动方程达到下一个状态。
那个状态呢同样有一个value,然后这两个y的和在不同的a之下,会有不同的值啊,因为我达到了不同的状态,然后所有a的最小值啊,其实是等于等于我当前这个状态的value function。
这就是bellman equation,那当by man equation有什么,就是它其实代表了什么,代表了说我这个value function达到最优的时候,如果它是一个最优的。
一个一个一个一个一个value function,一个值价值函数,那么其实它会满足这样的要求,那同时呢我们其实也可以得到,如果说我们已经得到了这样一个,最优的价值函数,我们的这个最优的策略啊。
不管它是什么,它是什么形式,我们总是可以写成这样的一个优化问题啊,就是根据就是前面我们说的,就是我们总是会选择一个action,它使得我后面这个大家函数,加上当前直接的代价啊,这样一个求和是最小的啊。
这是我的一个控制策略,但另外一个方面,我们其实也可以把它稍微转化一些形式啊,我们可以把后面这一这一这一片,这两个东西求和,把它记成q,一个叫一个q函数啊,用这样q来表示,它。
其实本质上就是我取在装当前状态下取一个action,得到的,这个当前就不管当前这个action的这个代价,以及我转移到新的状态下之后,那个状态下的value function。
那就是所谓的q function,那这个就是就是其实我们后面讲很多时候,比如讲q learning,就是或者reinforcement里面,其实我们经常会用到这个这个q learning啊。
这个q函数或者它另外一个名字叫state action value function,那其实都是一个东西,然后呢当我们知道q function之后呢,其实我们的派我们的pos控制策略。
其实也是可以写成这个这样的一个,优化的一个问题,所以说这个整个这个里边我们发现value function啊,或者是q function其实是很重要的一个一个点啊,一个一个一个这个啊一个这样一个概念。
就是我们很多这种优化,那最优化控制啊,或者是强化学习的这个好,这个算法其实最主要的目的就是学习这个啊,q v啊,就是value function和q function,因为我们知道他们之后呢。
那其实我们计算这个policy,就是相对来说比较容易的,那另外一方面呢,这个问题这个其实是一个优化问题啊,就是当我们得到v的这样一个函数表示之后呢,我们其实可以求这样的一个,整个这个函数的最小值。
但是呢这个最小值如果说a是离散的,就说如果说只有有限个a,那这个这个求解求解这个问题其实很好解的,我只需要去做一个什么,做一个所有状态下做一个线性搜索,那我们就可以得到这样一个v的值。
但是如果说这个a是一个连续的啊,就是这是我们的状态空间啊,我们的控制是一个连续的,就比如说非常典型的例子,离散的情况是什么呢,比如说我下围棋,但是围棋其中的风险非常大,我们可以稍微显简单一点的例子。
比如说这种,比如说下一个下一个猜拳吧,猜拳可能是双人博弈,哎呀这个例子就像他不太想,就比如说是一个非常简单,有少数控制策略,就比如说啊比如说玩游戏,玩游戏,大家手柄上是有有限个按键的。
或者你的键盘上是有限个按键的,那这种情况下你是可以比较容易的,只要我只要计算出value function,我就可以通过这种方式去得到我的action,但如果说我是一个连续控制啊。
就比如说就比如说我们在做这种啊,人体运动控制诶,怎么好像今天网络不太好,比如说我们在做人体人体运动控制,那其实人体运动控制会会比如我们运动的时候,我们加的力啊,他肯定是个连续变化的力。
而不是一个固定的力,那这个其实会带来一个问题,就是什么呢,对于a是一个连续的情况下,那这个优化目标可能是不好解,诶今天好像又是老是断线啊,行那就我们就我就尽量讲吧,那在这种情况下呢。
其实这个优化问题不好解,所以说我们通常来讲也是需要用其他的方法啊,去去去去定义这样的一个policy,ok那回顾一下,其实我们前面讲这两个,主要是讲了一个我们的这个最优控制的两类啊,比较比较基础的。
就是比较就是两类这个自由控制的问题啊,一种是我们的open开环控制,一种是这个反馈控制啊,对于开环控制来说,它它所对应的就是我的pmp啊,所以作为我的最优最优化的这样一个条件,而对于反馈控制来说。
这个bman equation啊其实是非常重要的,我们在求反馈控制的这样的一个过程啊,这样的一个这样一个基础,那当然我们比较关心的其实还是反馈控制,但实际上反馈控制里边这个v啊,和这个h大概就是v和派。
我们通常来讲想要去找到一个比较简单的解,或者说这种close form就是有确定明确的这种公式的,这种解是非常困难的,就是说其实对大部分的我们的这种机器,最优化和控制问题,我们都很难去找到这样的一个。
就是我们可以有显示的,可以比较比较比较容易地写出公式,去计算这个v的这样的一个一个方法,但是对于一些特定的问题啊,我们也这种一些简单的特定的问题。
我们确实是可以有这样的一个closed form的solution,就是一个呃有明确公式的这样的一个解,就比如说一个非常经典的例子呢,就是我们的l qr啊,就所谓的线性linear gradic。
regular regulator,这r q r问题,这也是控制领域一个非常经典的一个,一个一个弄一个一类问题,虽然说它是一类问题,但其实它能够解决的问题的范围啊,其实也是比较大的。
那我们说这个l q l有什么性质呢,它是一个特殊的啊,我们的这个最优控制问题,那特殊在哪里呢,首先对于这个object function,就一般来说。
我们其实没有没有对object function有任何的约束,但是对r qr来说,他会约束他认为这个object function是一个二次函数啊,单是高维的二次函数。
另外一方面它要求我们这个运动学方程啊,这dynamic function它是一个线性函数,感觉好像这个约束很很很大,但实际上比如我们之前有一个非常简单,非常提过的一个例子,就是我们在讲轨迹化的时候。
我们有这样一个例子啊,就是这个滑块他在放在放在这个,吊在这个数值的这个轨道上,然后呢我可以用一个力啊,用一个这个pd控制去控制它,然后我希望找到这么一个策略,它使得这个控制出来的结果是一个。
比如说某个曲线,比如正弦曲线,那当然我们其实可以推,我们当时是推过的啊,对于这样的一个pd控制,然后加上我们的欧拉的啊积分,实际上你得到的这个系统,你可以看到这个状态v和x速度和位置。
整体如果作为一个状态变量的话,你会发现这个状态变量在不断更新的过程中,它是一个跟我的这个上一帧的状态,以及我的控制信号是一个线性关系,然后下面这个优化目标呢,其实可以很明显看到它是一个二次函数啊。
这个sign呢其实无所谓的,因为sin是一个是一个参数,它是它是在整个过程中是固定不变的,不是我的就画对象,所以整体来说它是优化对象的一个一个,二次函数,那这个其实就非常典型的一个qr问题了。
那l qr问题就刚才我们就其实我前面说,因为它是可,首先它的目标函数是可以写成一个,二次函数的形式,那二次函数对于这个高维来说呢,其实就是就是类似于这样的一个,二次型的一个形式,同时呢我的状态转移啊。
我的运学运动学方程是一个线性方程,就是我下意识的状态,是上一个时刻状态的一个线性乘,一个系数乘一个矩阵,然后加上我控制信号乘上一个矩阵啊,得到了这么一个东西,那这个就是r q r,那其实回到我们前面的。
因为我们去如何去求解这个l q r呢,其实想一想我们前面提到这个bman quation啊,bin这个principle of optimial optimality,我们其实就提到了。
如果说我要想找到一个最佳的策略,那我其实这个最佳策略是,我只需要计算上一时刻就是下一帧啊,就下一个状态,所有可能性里的,这个就是所有在所有的下一个可能的,下一个状态,每个状态的这个这个这个value。
然后计算这个value呢,因为根据这个about my creation的这样的一个迭代,我们其实需要这个从这个状态出发的,下一个状态,它所对应的value,所以说我们可以不断的进行这个迭代。
所以说为了能计算s0 的挽留,那我们其实相当于我不断挤待下去,我需要先计算目标点的value,然后从目标点往回倒啊,依次计算目标点减一啊的那那些状态的value,然后再往前到再上一个目标点。
每一个状态的value啊,依次这样的迭代,那这个过程中实际上我们可以看到,就是我们可以进一步的看到,就说比如说对于我们前面的这样一个l q,r的一个优化问题,那它的优化目标是函数,是这样一个东西。
好或者这么写的优化目标是这样一个东西,它在最后一个时刻,也就是s大t在最后一个时刻,他的value function我们其实本质上也是需要去优化a t,然后呃对a t进行优化。
然后得到了这样的一个得到这样一个值,但是因为我们最后一最后一个状态下,它的value function or它的这个cos方式里面是没有a的,所以说实际上我可以直接得到对于目标点来说。
它的value就是就是我这个模呃,目标函数里边这一项在我知道这一项之后呢,比如说我现在往前看一步,我就看这个目标点,前面一步也就是第体检一步,那这个时候呢我的q function。
按照我们的那个bb quation的话,q function应该等于我执行at之后,我得到了一个下一个状态的德,然后呢,以及在t和t减一和s。一下,我的这个value function值啊。
这个object function的值,那这个该方式值在t减一的时候,时间只有中间这一项啊,只有中间这一项可以写成这样的一个形式,然后v s t我们刚才已经算出来了,他应该是这样的一个形式。
它就是s t啊,q s t,那其实对应这个技术,就是直接应用bmacquation,我们可以得到q s t一和s t演绎,这样一个表达,那接下来呢我们可以根据我们的运动学方程啊,这个可以告诉我们什么呢。
告诉我们s t s大t等于a啊,t减一乘以x减一,加上b t减一乘a t1 ,所以我们可以做一个代换啊,就是我直接把这st代换程度的,运动学方程的对应的项,那可以得到这么一个非常复杂的公式啊。
但其实本质上来说就是把sd展开成这样的形式,那就是得到家人,当然加上下坡有点长啊,得到这样一个形式,那这个形式下呢我们其实可以看到呢,这里面只有s t s t一和t减一,然后去加一些系数。
所以我们可以把它稍微整理一下,把那个s t和a减,s t减一和a点击分别合并同类项,然后大概得到了这样的一个公式,这是我们的q function,那我们接下来做的是什么,我们接下来是想。
比如说我们要求a按照我们前面的这个,bomequation的那一部分,这个这个定义啊,或者一个计算,我们知道a它是就是最优化的这个policy啊,最优控制的,下面这个得到这个就是最优的这个控制信号。
他应该是对q function啊,在对a去求一个最小值,那这个最小值其实对于一个二次函数来说,它的最小值是比较好求的,它最小值实际上就是我因为我对a,它对a是一个二次函数。
所以我只要把二次项的系数求一个,逆乘到这个一次项的系数上,那得到的值啊,那就是我的a的最小值,那其实可以得到什么呢,可以得到a的极小值,就是说使得q最小的,就说我那个a换句话说就是一个最优的a。
他需要满足这样的条件,那这个公式呢其实前面这一项都是固定的啊,就是都是一些确定的值,当然这s t加一是跟当前状态相关的诶,sorry,所以实际上我们可以把前面这段和起合在一起,写成一个。
因为它就是一堆一堆矩阵计算,我要把前面这一段写成一个,用一个矩阵来表示啊,就是一个k,然后你会发现呢,其实最优的这个策略跟我当前的状态的关系,刚好是用k啊这么一个线性函数啊。
这么一个矩阵乘上当前的状态计算,所以它其实就是一个先进的反馈控反馈策略,当然k本身的表达方式稍微复杂一点,但是这样的一个公式,这是我们得到了最取得极值点的时候a的值啊,当然如既然能算出a的话。
那我们自然可以得到这个v啊,v是什么,v是q在所有a上的最小值,那当然其实就本质来说,就属于当a取这样一个值的时候,它的最小,它得到最小值,难道这个公式会比较复杂,因为这个项数太多了。
但最终呢我们可以整理出这样一个情况,就是v t减一刚好是一个二次函数的一个形式,而且它跟前面的v t形式是相同的,唯一的区别,就是,中间那个p是需要根据这个qt进行计算的啊,这公式会很复杂。
但是我们可以确定的是,它它会满足这样的一个形式,所以就带来一个带来一个,非常有意思的一个过程啊,就是因为每一次我进行迭代,首先在t的时候,它是一个二次函数,非常简单的一个二次函数的形式。
在t减一经过我们一系列的计算,我们同样可以得到它是这样的一个t减一的,这样一个二次函数的形式,有这样的话我们其实可以进一步的类推,比如说在t减二的时候。
我们同样的类似的那个value function的值啊,其实也是这样一个二次函数的形式,所以说这样的话,我们其实构成了这样一个从后往前的这个,倒推的这么一个公式,在这个倒推公式过程中,我们会发现。
首先对于我们这个控制策略,就每一时刻,对于每一个t它的控制策略是kt乘以,然后这个k t是一个反馈系数,也就是说,实际上这一个这一个线性的一个反馈策略,然后这个线性反馈策略。
当然每一个时刻都是不同的这个系数,但是呢他在每个时刻下都会根据我,比如说这个s发生了一点变化,那我的a自然也会最优的,这个a自然也会发生变化啊,所以它其实是一个犯规,建议反馈控制。
然后同时呢这个建议反馈控制的计算呢,需要一些参数,这个参数比如说需要一个p这个参数,然后这个p呢其实是这个每一帧,每一个t所对应的这个value function,里边的这个二次函数啊。
的这个中间的这个二次型的矩阵,然后这个矩阵呢我们其实是可以得到,但是公式很复杂,我们总是可以从这个从最后一帧往前计算啊,得到这么一个递推公式,计算出每一个时刻下这个p的矩阵。
所以说也就是说这个l qr啊这样一个特例,我们是可以非常容易求解的,然后他求解的结论是,得到了一个每随时间变化的这么一个啊,线性反馈参数啊,所以它是一个线性反馈,也就是什么呢。
就是说比如说回到刚刚才我的问题,就是说那个我们那个那个那个pd控制的这样的,一个滑块的这样一个问题,在那个文里边,如果说我们要想这个滑块去沿着我的轨迹移动,然后同时呢比如这个滑块可能会有些扰动。
比如说我偶尔滴滴个滴个水上去用手拽一下,然后我还是希望这个滑块呢能够尽可能的回,尽快的回到我那个跟踪那个3d轨迹的,那个条件,那个程度上,那么我们就可以直接去施加啊,这样的一个线性反馈控制。
通过r qr去计算出来的,那这样的话,它这样可以保证我的滑块在扰动之下,能够始终满足那个跟踪我的轨迹,那当然确实这个l q r它的条件是什么呢,就是它是它能够成立条件。
比就是要求我首先我的这个运动方程是线性的,同时呢我的这个project object function是一个啊二次函数,那对于简单的,比如刚才那滑滑问题是非常容易的,甚至可能再复杂一点问题。
可能就比如说发射火箭,我该怎么去控制这个火箭的速度,那其实很大程度上它也是一个线性,你可以把它这个某种程的线性化,但是呢我们该如何去处理一些更复杂的问题,比如说人体的动作,我们不断的强调人的动作。
因为它涉及三维旋转,它是一个非线性的一个问题,它的这个运动学方程是非线性的,就是其实速度的部分是线性的,但是从速度到这个角度的这部分是非线性的,另外一方面呢,其实我们很多时候。
我们会定义一些更加复杂的函数啊,大部分情况下它是一个不是二次曲线,而是一个更加通用的一个函数,那这种函数该这种时候该怎么办呢,那这个就是我们一个都更通用的一个,非线性的问题,就是我们前面提到的。
我们要优化一个这样的一个求和啊,随时间积累的一个优化目标,同时呢要求他满足我的运动学方程,那为了能够让这个因为我们l q l,我们知道它是一个比较好解的一个问题,所以实际一种思路呢就是把这样一个问题。
把它给线性化,把它近似的变成一个l qr问题,那在这个过程中呢,首先啊h啊h是一个非线性的一个函数,很复杂的一个函数,那当然我们其实还是有些晕,有些这种假设的,我们就假设这个h它是性质比较好的。
它可以它的展开,那我们可以在h在某一个点附近的,某一个初始解附近把h进行展开啊,展开二次项,那就得到了一个这样一个quetic的一个,二次函数的这样一个优化问题,同时呢进一步的f也是一个非线性的。
也是一个这个非常复杂的函数,再如果说我们依然也是,假设它的性质比较好的话,那我们可以啊既同样用同样可以对f进行展开,比如斩到一次项,或者是可以展到二次项,取决我这个f的形式,如果斩了一次项呢。
其实它对应的一个算法叫做iterative i l q r,不是q r s iterative l cr,讲到二次项呢,其实对应另外一个算法叫dynamic programd d p啊。
那这其实也就是说我们在求解非线性的这种呃,最优化问题的时候,最优控制问题的时候,我们可以做的一些一些一些策略。
当然使用最优化控制啊,来实现全身的动作,其实这个也是嗯在就是之前很久之前,也是有一个非常好的一个工作,但是2011年,其实这是在2009年,他们有了第一篇工作,后面1年的时候就做了这个稍微做了一些改进。
那其实从当时来看,这个效果还是相当不错的,就是我们通过这个最优化控制的设计,可以让这个角色能够在我们外界的控制之下,进行走路啊,那同时其实也可以有一些扰动,能够让这个角色能够做出回啊,做出这个反应。
那当然最优化控制一个最大的问题是什么呢,就是说,他的这个表现。
随着我前面这个优化问题的这个嗯,函数就q和r其实是影响比较大的,所以说实际上选择这个比较好的科幻,而能实现一个好的动作,其实是一个需要一点工程上的一些一些技巧,另外一方面为了求解这个问题的话。
其实我们是需要去显示的,去建模我们的这个用方程的,那这个其实就涉及到这个所谓的model base的方法和,model free base,model free的方法的这样的一个区别啊。
其实我们前面本来说这个有最优控制,最后控制一个最大的特点呢,就是说我们其实所有的控制,我们都是假设这个运动方程是知道的,如果不知道的话,那我们前面最后控制那些推导,其实是没法推下去的。
那这种方法基本基本都是所谓的这个model base的方,法,就是我们知道我们这个运动方形的模型,我根据这个模型来进行,我这个运动控制的这个计算,但是其实model base方法在很大程度。
很多时候是有一些局限性的,就比如说我这个model这个函数啊,在很多时候首先他可能是不知道的,其次呢是这个函数本身可能是不精确的,其实最简单的这两条,其实都是对我们这种人的仿真,或者是这种一般物理动画。
都是非常非常呃成立的,就是说什么呢,就比如说这个碰撞的模拟,碰撞的仿真,我们通常比如说我之前讲到了,我们可以把它描述成一个penalty,描成一个pd控制,或者说描述成一个l f q r问题。
一个线性互补问题,或者描述成一个约束,但不管哪一种,其实都是对一个真实的碰撞过程的一个近似,那这个近似很多时候是不太准确的,就比如说非常比如说我们常用的所有l q啊,l c p,不好意思。
l cp就基于约束的这样一个运动方程啊,这样一个碰撞方程它会有什么缺点呢,就是它比如说它不太会容易反弹,所以正常来讲我扔一个东西掉地上,它其实会弹起来,但是基于约束的话。
它是它是这个反弹的效果是不大容易去实现,还有比如说像摩擦力的这种这种仿真,其实不同的这种这种模型也会带来不同的效果,所以总体来说呢对于一个真实的问题,或者对于一个真实的这种机器人,对于真实机器人来说。
首先你的测量是不准确的,你总是会有误差,其次加上我们这真实在仿真里面的建模,跟机器人之间建模之间的这个真实世界,这个区别啊,其实会导致我的仿真里边我不管怎么样去建模,这他都跟我真实的世界是完全不一样。
那除此之外呢,其实这个整个过系统过程中可能有些噪音,这其实对于真实机器人很常见的,我运动一下,不管我的控制方面,还是我的这个传感器都会有噪音,然后以及比如说这个问题本身是一个非常高。
highlion linear的,比如说我们前面提到的运动,那这种情况下,比如说我先计算它的这个梯度的各种技术,或者计算前面的这种,比如说这种泰勒展开,那你会发现我需要算梯度。
如果这个f的性质很差的情况下,你的梯度基本来说是这个很难,基本来说不会给你带来非常有用的信息,所以在很多时候的话,我们可能model base方法对于复杂的系统来说,可能有时候是很难去使用的。
但是对于简单系统来说,model的话其实会比说是一个非常高效的,并且非常呃有效的,就是这个就是可解释可分析的这么一类方法,那就回到这个,其实后面我们很多方法都是所谓的,model free的方法啊。
包括这个其实我们前面已经用过了,像这种cma啊,用这种啊基于采样的方法去做轨迹优化啊,包括后面我们稍微提到的,这些基本都是model free的方法,就是我们在不知道model的情况下。
我只知道我的优化函数我该怎么优化,当然这里不知道model,是只是说我并不知道model这个,我这个动运动方程的一个准确的表达,但实际上呢我还是需要能够去仿去聊,去使用这个运动方程。
就是我总是需要能够从某种方式,用仿真的方式来计算出下一个状态的state,那在下一个时刻的这个这个状态,那这种情况下,虽然说我不知道这个方程它是一个黑盒子,但它总是会告诉我下一个状态是什么啊。
这是这个model free方法的一个基本要求,那当然回到我们前面这个问题啊,就是说实际上一个非常常一个非常常用的一类,这个model free的方法呢,就是比如说我就基于采样的方法,来进行这个优化。
那我们其实讲轨迹优化时候提到这件事情,就是说我们是可以用比如说sam啊,sam e s,这其实是一个非常经典的一个基于采样的一个,优化方法去优化我们的这个控制轨迹啊,或者去优化一个开环这个轨迹。
但这里呢其实我们可以同样用类同样的方法,来实现对于控制策略的一个优化,那当然其实跟前面相同相似,只不过我们目标变成了一个控制策略,那整个过程也是,我首先是对这个控制策略进行参数化。
比如说它可能是一个一个,比如说一个线性函数啊,比如那个矩阵,那就是那个线性函数里边,这个这个矩阵就是我的化目标,那当然也可以更复杂一点,比如他一个神经网络,那神经网络的系数,那也是可能是我的优化目标。
那这个优化目标在这个u是,他这个给出这么一个policy,这样一个目标函数之后呢,我们是希望能够去找到最优的这样一个参数,它使得我的前面的这个这个加和,求和的这样的一个啊优化目标能够最小。
那当然这个优化过程,就首先我可以初始化这样一个sea啊,然后接下来呢我可以去不断的产生若干个,对这个theta做一点扰动,产生若干个,这在这个thea附近找一些可能的更好的theta。
那接下来对于每一个这样的一个策略,对于failed i的这个策略进行一次一些仿真,仿真,完了之后呢,对于每一个仿真我都会产生一个轨迹,一个仿真的轨迹就在这个仿真轨迹上,我们可以去计算我们的优化目标函数。
那接下来呢就是根据这个计算得到的结果啊,我们去更新这个theta,那怎么更新呢,其实不同的方法也不同的这个更新策略,比如c m e s,那本质上就说把认为这个fa是一个高斯分布啊,是一个正态分。
高维的正态分布,我每次更新的时候,我是更新这个正态分布的平均值和方差,然后让它逐渐的移动到我们最终的那个目标值,的这个目标解的附近,当然这个是我们以前的一个工作,就是我们可以通过这样的一个直接去优化啊。
用cmc进行优化,来实现一个比较复杂的一段动作,当然这个过程其实我们可以稍微多练多讲两句,就说这个我们该怎么去实践,这么复杂的一个控制来,首先就是大概是三步走啊,首先是我们先要找一个开关控制。
因为这个本质上来说是,因为我们这个使用了一个线性反馈控制,所以他要求线性反馈,控制线性的东西就说明什么,他不能离不能离开太远啊,就离开太远的话,就是因为很多时候,我们需要在一个函数进行线性化。
那信息化肯定是离这个函数越远越不准,就是泰勒展开的这个这个,这这些得的给我们的一些基础基本这样一个词,结论,我们首先可以通过一个开环的一个轨迹优化啊,比如说用三卡来得到一个开环控制轨迹。
那开关控制轨迹是好处是什么呢,就是说我直接执行这个控制的这个轨迹,这样一个action系列,我大差不多是可以得到一个相似的动作,那当然缺点是什么,缺点是如果说我这个状态被加了一些扰动。
扰动了另外一个地方的话,我那个开关策略是不能去更新它的它的位置啊,它的控制信号的,那这个时候呢我们需要反馈控制来去更新一下,我的这个控制信号,使得我这个被反馈sorry被干扰过的这个状态呢。
还是能回到我的目标状态附近,那在这个里边呢,其实我们会非常简单的就认为我的这个目标,这个干扰所带来的状态偏移,跟我所需要施加的这个控制信号的拼音,他俩之间是一个线性关系,就乘上一个系数就得到了这个值啊。
当然这也就是说这个前面是这个线性关系,这个它代表了这个状态的变化和,控制信号的变化之间的关系,当然了,其实我们也可以进一步的把m做一下分解啊,我们可以把m写成两个更小的矩阵的乘积啊。
这两个小矩阵是什么呢,就是首先一个是把从一个比如,很高维的一个状态表示,把它映射到一个低维的状态表示啊,我乘上一个一个扁的矩阵,然后呢再把再把这个扁的这个小的表示呢。
再映射回一个完整的一个控制信号的表示,就成了一个高度矩阵,这样春节的好处是什么呢,分解的好处是说我可以首先它的这个参数量啊,它是一个矩阵嘛,所以它它是它的整所有的参数量是长乘以宽。
那长城宽带其实有些时候它数量会非常大,其实对我们的优化来说比较困难的,而如果说我们选择一个比较好的中间这个p啊,这个这个小的这个值,然后这两个值一个是瘦高了,一个是矮胖的,他们整总量的这个参数。
会比原来这个m要小很多啊,其实这也会让我们的优化更加简单一点,当然另外一个角度讲是什么呢,就是实际上也是通过这种变换的,我们其实可以强制的把我们这个状态里边,不需要的信息啊,从我们这个控制里边去拿掉。
那当然为了实现这个控制的话,我们其实还是加了一点工程上的一些trick的,就比如说我们的这个state表示,通常来讲我们讲一个state,一个角色的状态,那它其实你可能包括包括所有的关节的旋转。
包括所有的这个钢铁的位置等等等等啊,那但是实际上为了能够实现这个线性函数啊,能够工作的更好,我们其实还是手工挑了一些,这个非常有效的策略,但是实际上这个也是非常有有这个道理的。
就比如说我们这个状态表示包括了什么,包括了这个包括了至今位置啊,包括了这个这个最近的速度啊,包括了根节点的这个旋转,包括了这个根节点啊,就至今到这个支撑脚的位置,其实回想一下我们上节课讲这个走路啊。
我们知道其实这个质心和这个支撑脚啊,ort polygon这个相对关系,其实对我平衡是非常重要的,那其实相对来说呢,反过来这个控制我们其实也不是,也是通过一些挑水就是选择出来的这个关节。
就比如说我为了能够实现跑步,实际上我们只需要在少数几个关节上,加上反馈啊,就可以让这个角色能够比较稳定的奔跑啊,并且这个能够承受一定的这种扰动,那这个其实主要就是对于平衡来说。
一般就是hip就是两个髋关节,还有腰部关节就可以实现这样的跑步了,那剩下的其实主要就是优化了,如果说在我们如果说我们认为好经理,好这样的一个线性模型之后呢,我们其实可以直接用cma啊。
按照我们前面提到的这种基于采样的这个,优化过程来实现一个对这个优化目标,就是我们这个中间这个线性的反馈函数啊,反馈的这样一个系数,但实际上呢,这种优化其实比我们现在常见的那种强化学习,要快很多。
因为确实因为这个策略本身是比较简单的,而且呢这个参数量也是非常小的,所以实际上大概十你跑个几分钟就能跑出来,只能实现一个类似于这样的,当然这个效果其实本最主要的还是,因为我们首先有一个开关控制。
在这个基础之上呢,我们再去做这样的一个线性反馈,它就能实现这样的一个比较复杂的,这样一个一个一个运动啊,当时看起来还是比较复杂的,现在感觉好像是一个比较简单了哈,大家随随便便用这个强化学习。
就可能实现这样的一些动作,但是非常有意思是说,它只需要这个线性控制,而不需要更复杂的,像这种这种这种这种神经网络,就可以实现这样的效果,ok那我们其实前面讲的都是这个自由控制啊,但自由控制。
但是呢我们后面就是现在大部分的情况下,我们这个新的一些更好的工作,更高效的工作大部分都是用的这个强化学习,但实际上最优控制跟强化学习之间,是有非常强烈的这样的一个关系的,实际上你要是了解更了解的话。
我们可以发现,首先这个强化学习和自由控制,他们是有共同,差不多相同的这样的优化目标的啊,基本来说都是一个每一个时刻,我会算一个代价函数,然后呢这个代价函数在所有时间上,这个轨迹上啊进行求和或者积分。
然后在这个基础之上呢去,比如说有这control,可能我求的最小值,这当然只是属于这种问题本身的一个啊,就是一个通用的这样的一个写法,但实际上对于这个最优控制,或者或者最详细来说,我是求最大值和最小值。
其实都是无所谓的,关键是我要求这样的一个最极呃,呃一个最优质啊,但是对于一般来说,对于强化类学来说,可能就一般求最大值,是一个比较常见的这样一个写法。
ok这首先首先reinforce learning和optimal control,他们的这个首先研究的目标是相同的,基本来说,但是呢最优控制我们前面提到了,它一般是一个基于模型的方法。
就是它是要求我们知道,这个系统的所有方方面面,我们可以非常精确的写出,这个这个这个系统的运动方程,但是强化学习呢,一般来说我是不要求我知道精确的,这个运动方程的它是完全是通过什么。
通过我不断的跟世界进行交互,进行采样来去更新我的策略,使得这个uri函数的这个区的机制,虽然说这个rl啊就是我们强化学习呢,不要求我一个非常准确的一个系统描述,但是呢他还是可以利用一个一个比较好的一个。
系统系统模型来帮助他进行学习,那当然这种新的模型,一般来说通常来讲我们是不是指针的系的模型,我们可以通过数据来进行学习,然后学到一个模型,然后再用那个模型来去指导我进行更好的爱。
那当然这是也是一大类这个强化学习的方法,叫model basil,就是他其实是说我该怎么去学习这样一个模型,然后以及怎么用,怎么利用这个模型去帮助,更有效的去学习这个一个控制策略。
那当然我们可以再稍微多讲一点,那就更详细的介绍一下rl的一个基本知识啊,我们前面提到的就是i l rain f,reinforce learning或者强化学习,它实际上是在求解一个什么问题呢。
实际上一个叫mark decision process的这样一个问题,马尔可夫决策过程,那这个结果呢我们大家可以简单的描述一下,就是说我们这个系统整个这个环境里面,整个这个系统里边有有有两个主要的对象。
一个是以我们的这个agent啊,我们的这个优化了这个,执行我们这个策略的这么一个小机器人,然后另外一部分呢是我整个外界的一个环境,那这个环境可能是很复杂的一个环境,那在整个这个过程中呢。
我这个小机器人它根据某一个控制策略去执行,去用这个控制策略,会根据当前这个小机器人的状态呢计算一个action,计算一个控制信号,然后那小气人在这个环境里边,去执行这个控制信号,会让我这个机器人。
它的状态呢更新到下一个状态,那同时呢这个这个环境也会告诉我机器人,你在执行这个东西过程中,我获得了什么样的代价,或者我获得了什么样的这个奖励,那我最终的这个整个,比如说我可以不断的执行这个循环的。
what,我从s0 开始直接嗯取得s a0 ,然后得到到达s1 ,然后取得a1 ,到达s2 啊,直接是得到了一个很长很长的一个轨迹啊,我会我们之前一般一般来说,我们叫它仿真轨迹啊,或者叫这个控制轨迹啊。
都可以,然后在这个轨迹上,我可以把每一个时刻的状态积累下来啊,那最后得到积累一个值,其实就是状态在s0 时刻的return,就是在从s0 出发执行一系列action。
执行这个不断的执行这个policy的轨迹,轨迹上的这个求和就是这个这个这个点的turn,当然这个rl 0里边,就是我们后面很多研究的很多问题呢,都是一个假设这个轨迹是无限长的。
那当然无限长其实会带来什么问题,就是如果说像我们这个最优化控制里边,我们直接求和,那如果是一个无限长的轨迹的话,然后如果每个轨迹的这个每个点,它的值都是大于一个,有一个有一个下限的话。
一个非零的下限的话,那你会发现这个无限长的求和之后,这肯定是无限大,那这个问题就没法解了,所以通常来讲呢,我们是说我们会考察的是一个discounted啊。
就是一个就是卖这discounted这个这个reward,就说其实我每一帧上revert,前面我会加一个系数,这个系数gm是小于一的,那通常来讲我们会取很相对来说很接近一的值,比如0。9啊,通常点0。
99啊,有些时候还0。999,但是它的效果就是说我随着的轨迹越往后,我认为后面的状态,受到当前这个状态影响会稍微小一点,因为中间有很多各种干扰,然后同时呢我在这个状态所能获得的,这个就说或者另外一方面。
我可以认为离我这个当前状态非常远的,那些状态呢,它的好坏是不影响我当前这个状态的判断的,所以是这样的一个reward,那就是一个非常典型的例子啊,就是说我们其实是可以把一个跟踪问题啊。
其实本质上是一个轨迹优化问题,我们其实可以把它变成一个m m d p问题啊,其实主要就是reward这部分,我们不就是像我们这个用这个啊,做轨迹画的时候一样啊,我只要去用我的仿真的结果。
剪掉我的参考数据的结果做一个差啊,作为我的reward function,那这其实就是相当于用一个i l,用一个强化学习来实现一个跟踪控制啊,这样的一个效果,当然从数学描述上来说呢,一个md p问题。
那他其实可以更加数学上描述,它是一个离散时间的一个随机控制问题啊,一个随机控制的一个过程,但是整个整个m t t就包括i l,它其实是一个非常好用的一个framework。
就是我们可以用它来去做一些非常复杂的一些,问题的训练,男人最基本的一个要求,最基本的一个条件,就是说,首先它不假设我的这个probability是知道的啊,当然是我是要求这个系统是有的。
所以说我可能会不知道他另外一个呢,就是它是一个mark,一个马尔可夫的一个角色过程,什么是马尔可夫呢,他就是就这他肯定是要有马可马可夫斯property,就一定要马可夫,马尔可夫性这个性质说的是什么呢。
就是说实际上我们其实前面一直在讲了,他只是没有显示的把它说出来,就是说我们这个状态下,意识的状态只跟我当前时刻的状态相关,就如果算就是在我知道当前状态之后呢,我下一时刻的状态只跟当前状态相关。
而不会跟我之前所有的状态,任何一个时刻的状态相关啊,这其实就是就是马尔可夫信,那更加这个这个精确的这个mdp的定义啊,时间通常来讲是给出一个四元组,那这个四元组里面。
首先是我所有可能的action的集合,那它可能是一个连续的空间,也可能是一个离散的空间,然后a是一个所有可能的控制信号的,这个action的空间,那这个p其实是一个状态转移的这样一个概率。
不是其实也就对应的我的音乐学方程,但这个运算方程呢就虽然我是形式上写在这里,但是我们可以是可以,它可以是不是大的,然后r是我的这个reward,就是这个代价函数o那我求解mdp问题。
我们其实是要干什么呢,我们其实是去寻找一个policy pie啊,跟我们前面的这个option control是一样的,然后呢他去优化一个expected return啊,这个其实是有点不太一样的啊。
就是说在我们前面所讲最优控制的时候,我们很多时候是就是直接找最优解,就直接优化那个这个方程,但是我对于这个mt问题来说,其实mtv为什么我们去找这个expected return。
其实本质上还是因为这个派在前面我们讲一哈,但是这个我们前面只是讲了一个所谓的这种,deterministic object object,说。
就我们假设那个派是一个是一个deterministic function,就是一个确定的函数,那实际上我们在这个mtp问题里面,我们会需要假设这个派,包括我们所有的状态转移,它都是有一些噪音的啊。
就是比如说这个控制噪音,和这种这种传感器的噪音等等等等,这些噪音会带来什么呢,就会带来我这个控制这个实际世家这个控制,还有我这个状态转移都是一个概率,我会转向哪个状态下。
都是一个都是在一个随着概率去进行进行变化,那当然时间有些人可能不一定是噪音,就可能这个系统本身就是随着概率变化的,比如非常简单的一个例子,就是那个薛定谔的猫吧,它是随着概率去进行变化的。
你看在这种情况下呢,我们其实去找这个,我们通常来讲会把它定义成啊,去使得我的这种所有状态下的这个期望值啊,得到最大,这是我的优化目标,那这个状态就是就是,首先嗯这个期望是在哪算的呢。
是说我通讯从任何一个状态出发,然后用我执行我这个派啊,不断的执行过来,派得到一个轨迹,得到一系列的轨迹,然后在所有的这些轨迹上,所有可能的轨迹上,因为每一条轨迹会给我一个这个return。
在所有可能轨迹上计算这个return的这个期望啊,那它其实就是我的优化模优化函数,那其实可以稍微再比较一下,其实在我们讲这个optimal control的时候。
我们讲value function是这样的一个形式,是一个about my equation,然后这个其实q function或者state action。
one function其实也是一个ban equation的形式,在我知道湾流方式之后呢,我的派其实就是求这样的一个最优解啊,这么一个函数的这个自由值,可以得到我的控制目标啊,控制信号。
那l里面呢其实在特别对连续的l,其实对于这种离散的l,其实我们同样其实也是可以用前面证方式的,对于连续函数,就是连续状态空间和连续的这个控制信号下的,i o的话,我们大部分情况下是我们这个定义。
value function呢是通常来讲是定义到一个派,就是针对某一个派某一个控制策略,而不是最优策略啊,比如control里面这几个其实对应的是最优策略,而对阿里,阿里边,我们很多时候是说。
我们这个value function是根据当前某一个策略,定义了一个value function,他是说他是在这个策略下,在这个policy下我执行的所有可能的这种轨迹,仿真轨迹啊。
所计算这个return的值啊,这是value function,那q function也是类似的,同时他们也是可以满足我们前面的这个,bincreation的这样的一个迭代的一个形式。
那这个其实也是在我们这个强化学习里面,非常重要的这样的一个相对关系,因为为什么,因为我们后面很多强化学习的方法,很多都是基于这样的一个嗯,government equation进行设计的。
就比如说这种常见的value base的方法啊,value base方法其实基本思想啊,就是其实我们就是说我们去计算啊,这个value function或者q function。
它其实q方式本质上也是一个value function,然后在这个过程中呢,我们去不断的产生新的这种trajectory,然后在这些新的trajectory上,我们可以前前后两帧去计算。
这个利用这个迭代公式去计算我的value function,去期望的value function的值,然后呢,再让我这个当前value function,去跟我期望那个直径可能接近啊。
通过不断的优化这样的一个一个代价函数的,这样一个表示,来最终得到一个最优的一个代价函数,那我得到最优大函数之后呢,那其实我们要对应对应得到那个控制策略。
就是最优代价函数的最优的这个q value function啊,对每一个action取最小值或者最大值,包括这些法,那就可以得到这样的一个控制策略,那这种value based method。
value based的方法,很多时候是使用在这种所有离散控制信号的,这样的一个问题里边,有一些非常经典的一些算法,比如说valuation,比如说q learning啊,比如说d q n。
其实dq n是一个非常有意思的一个工作,就是应该说怎么说呢,就是说d q n是首先这是发表在nature上,natural nature上的一个工作,应该说某种程度上,它开启了一个强化深度。
强化学习的一个一个新的,这样的一个新的几个时代,或者说就是实际上一方面让这些东西变成了,一个大家都知道的一个问题,另一方面经常提出一系列方法呢,也推动了我们后面强化学习啊,包括强化学习。
在这个解决动画还有很多其他领域的应用,他实际上说什么,就是它是通过q learning去控制这样一个摇杆去移动,当然摇杆其实你想一下,好像摇杆是一个连续的空间,但实际上他是把这个摇杆的可能的。
用这个控制方向做了一个离散化啊,所以他最终只有十几个啊,不同的这个控制策略啊,控制信号,那实际上最终他是去通过这个value方程的学习,找到在当前某一个状态下,比如这一帧啊,这个图像状态下。
我们每一个摇杆移动的方向,所对应的这个这个q36 ,那得到这个之后呢,我其实可以去找最大值嘛,因为只要做一下所有所有可能性的便利,找了个最大值,那就可以去控制这个脚本移动。
当然这个工作是他实现当时那个论文啊,它就相当于我通过这种简单的策略,简单的这个代价函数加上训练,我就可以实现一个人去玩这个游戏,所能够达到这个平均分数啊,甚至比人的平均分数还要高啊,这是这是2015年。
这个工作其实也是非常经典的一个工作,deep mind,其实从这开始,人蒂姆曼呢,其实后来变成了一个非常知名的一个。
这么一个这么一个学术机构,那当然在决斗动画里面,我们其实也同样的,可以用这种d q n来进行一些,比较复杂动作的控制,当然地科前面也说到了。
他这就是这种value from sorry value方程的方法呢,它一个非常基本的要求,就是我的状态空间,不是我的这个控制空间是离散的,就是我状态空间可以是连续的,但是我的控制空间是离散的。
所以实际上我们是可以用它来做什么的,可以用它来做一些高阶的控制啊,就比如说这里面我们这是我们之前的一个工作,他做的是什么,就是我其实先学一个控制器,那这个控制器里可能是这个人在在这个玩滑板。
但是玩滑板的过程中呢,其实比如说这个角色,他比如说撞到的物体,撞到物体,他如果继续去执行之前那个玩滑板的动作的话,那可能就摔倒了,而使用,所以实际上为了能够能够去不摔倒。
他需要去跳转到某一个滑板的技术上,然后在这个基础上上,他可以去比较好的,比如用过这个坡,那这种情况下我们该怎么去选择哪一个节,哪一个时刻去进行跳转或者跳转的哪一个,这个这个控制器的哪一部分。
那我们其实可以通过这个d q n来进行实现啊,就是本质上我们把这个把这个我所有的控制嗯,整个控制策略给切成片儿啊,切成按时间进行切片,然后它就是一个离散的一个状态空间,那我们就可以用dq n来实现。
这样一个完整的控制,然后当然另外一类啊就是强化学习的方法呢,就是所谓的policy gradient approach啊,其实policy green呢其实还有另外一个。
就跟那个value方式合在一起的,叫after critic,其实本质上来说,它是policy gradient跟那个value function,base的方法的一个结合。
那policy gradient的方法,其实跟那个前面的这个value function,那基于value function的方法其实是啊第一步是一样的。
就是我其实最终还是需要去学习一个value function,但这个value function我们还是需要通过比如ban equation,或者说如果说我可以得到长序列的话。
那我当然可以直接对长序列直接去计算,那就不需要把我们equation了,我总是需要,但是不管怎么样,我总是需要这么一个东西来去近似的去学习,value function的一个表示。
然后有value function之后呢,那我们就可以通过我在仿真,得到的这些仿真的样本点,通过这些样本点利用这个蒙特卡罗法啊,去一个进去计算一个近似的一个policy gradient。
想一想我们前面讲这个啊优化一个函数,那我们其实求的是这个函数本身的gradient,对于pology来说,其实我们也是为了能够优化他,为了能够让他调那个呃,因为本质来说我们去优化一个policy。
我们是希望他能够优化我整个的value function,所以实际上我们需要计算什么,我们最终计算policy gradient,它实际上是value function。
对我们policy的参数进行求导得到的那个gradient,那当然当然这个直接计算是没法算的,因为因为仿真的这个模型我是不知道的,所以你没法算,所以说这种policy green的方法。
一般来说是通过一些统计的一些技巧,把我们不能算的部分从我们的公式里去掉,那他得到一个对policy gradient的一个近似,那得到这个policy gradient之后呢。
我们其实就可以直接可以用gradient decent,gradient ascent去更改为pc值,但这种好处是什么呢,就是说实际上在这个整个计算过程中呢,我同时有两个函数在进行更新。
一个是value function,另外一个是我的policy,是一个显示的定义好的一个policy,它可能是一个神经网络啊,可能是另外一些奇奇怪怪的一些表示。
而前面这个value function的方法,这个value function其实里边它policy是没有显示定义的啊,它它是它只有value function是是显示定义的啊,所以这是这两种方法。
两类方法的一个非常大的区别,那当然既然我显示的定义了ctrl policy的话,那我就不需要去求解那个优化问题,去找到下一个action,我只需要直接去啊对这个policy的函数进行求职啊。
就可以得到我需要的action,所以他对于这种连续的问题呢会更加有效,那其实非常经典的一些方法,比如rain false,比如说这个t r p o,比如p p o其实差不多都是这类的方法。
那当然这方法这类方法其实特别是p p o啊,应该说是在这个角色动画领域,特别是物理学的动画应用,是非常非常广泛的一类一个方法,但这种某种程呢也是因为什么呢,就是说rl的方法其实蛮多的。
但是实际上就是特别,但是很多时候包括啊一些这种新的方法,因为本质上来说它是最关键的一步是什么,是这个计算这个approximate policy gradient,这一步是比较关键的一步。
然后很多我们现在常见的这种强化学的方法呢,它都是基于一个假设,这个假设是什么,我假设我踩了无限多的样本,然后在这无限多的样本点下,我用这个求这种求这种期望的方式,去计算这个progreate。
但是在真实的这种场景里面,我们是不可能采无限多的sample,而且实际上对于比如说我们人人的控制啊,角色动画的控制,我的整个状态空间的维度是非常高的,那在维度非常高的情况下呢。
我其实撒上几万个点在里面踩着几万个样本点,比如对于一个100维的空间来说,它其实也是非常非常稀疏的,所以实际上这种情况下,就是很多时候方法来说,他所得到的效果,可能跟理论分析上多少会有一些出入。
所以实际上我们大家很多时候用的方法,都是说什么,都是我们这个方法本身,就是说可能在大家很多人用了之后,发现他这个这个实际的这种鲁邦信啊,或者有效性啊会相对好一点,所以大家都得用,那当然确实为什么。
就是这个这个pu大概这么多,因为确实pu它这个实际效果还是蛮好的,当然一些很多其他的方法可能效果更好,那当然只是说这个我们现在这个,大家在使用上来说还没有这个注意到,但是不管怎么样。
使用这个reinforce learning,加上一点点的这种轨迹优化的控制,我们就可以实现非常复杂的动作,比如说其实现在应该说比如说用用这类的方法,只要我有一个动捕数据啊。
当然只要当这个动捕数据可能只要要代价,这个质量不要太差,只要这个动作数据不管什么动作,我们都可以去学习一个控制器,使得我这个物理仿真的角色能够做出这个动作,而且时间在这个过程中。
我们其实可以调整很多参数,比如说我们可以调整一些,比如这个角色运动的速度啊,比如只要调整一些这个角色的这种高矮胖瘦啊,把这些东西作为额外的参数给我的这个控制,控制控制策略。
它就可以让我的这个得到这个反呃,运动控制,能够自动去适应,这不同的角色和不同的控制信号,所以这其实是就是强化学习带来的,这个我们觉得动画里这个物理学,动画的一些一些这个非常大的一个进步。
那当然其实可以有一些更加有,稍微在这个基础上可以做一些应用啊,就比如说我们可以根据更多的这种,那我们把大量这种控制器控制,不同不同的这种控制策略啊,放这个把它结合起来。
比如说像我们motion graph一样,我们可以做一个control graph,然后用状态机的方式来实现,对一个角色的一个访客控制,另外一方面呢,就是说其实前面我们这这几种常用的这些。
比如这种跟踪控制,我们通常会把这个角色啊控制性策略,sorry,我们在控制我们的这个这个control policy,我们的控制策略呢,通常会把它建模成一个神经网络,当然神经网络这里其实从结构上来说。
可能有就有很多很多不同的这种技巧了,比如说非常我们前面提到的,在我们讲这个这个运动学的生成啊,基于学习的这种运动学学动画方法的时候,其实我们也提到了,我们其实后面有很多方法是利用各种,比如说生成模型。
来实现对这个不同可控的这样的一个,角色动画的生成,那这些生成模型比如说包括什么呢,像是auto encoder啊,vae啊,包括gun大家非常熟悉的这种对生成对抗网络,包括我们的这个就这个标准化流。
包括在今年特别火的这种啊,diffusion model就是扩散模型,其实这些生成模型带来的就是,从这个网络结构上的这种新的设计,同样的是可以使用在我们的角色动画里边啊。
sir物理角色动画里面使用在我们这个reinforce learning,强化基于强化学习的这些控制策略学习里面,就是我们需要把这个控制策略的部分,换成相应的这种强化学习的网络。
surprise生成的网络,那当然这里带来一些问题是什么呢。
就是强化学习其实非常大的一个问题呢,是他经常来说它不是非常稳定,就是我们前面讲的,比如运动生成模型里边,我们其实是可以直接的去通过这种啊,所谓的supervised learning啊,就是这种这种呃。
这种监督学习来实现发这个学习,但这个相对来说,监督学习是一个非常稳定的一些学习方法,就是我可以每次运行啊,可以不用怎么调参数,就可以得到一个相对来说还可以的结果,但是那个前面几种方法里边干啊。
就是对抗生成网络,其实是一个也是一个非常典型的一个不稳定的,一个也不是很稳定的一个训练过程,就是说因为本质上来说,它其实那也不是一个非常直接的一个阶段学习,还是通过得那个一个判别器来进行这个。
这个这个监督,所以对于rl来说,其实虽然说我们可以换成不同的这种生成模型,网络来实现一个类似于我们前面提到生成的效,果,就是生成效,其实这里就是一个非常生成模型的一个例子。
其实我我可以去随便给一个随机的一个噪音,它会通过仿真得到一些完全不同的动作,那这其实是生成模型带来一个非常好的效果,但是学习这样一个生成模型,通常来说相对困难一点,一方面是rl的这个这个不稳定的问题。
另外一方面这个生成模型本身啊,不同的生成模型可能也有相应的不稳定问题,所以说其实解决这些问题呢,也是我们这个最近一些工作的一些,一些一些重点。
当然现在其实觉得模型其实也是做到了一个嗯,就是也是到了一样一个状态,就是我们其实我经常跟别人提到,我们角色动画领域的这个好多不同的这个呃,技术的这个发展过程嘛,其实我们前面也提到。
像是这个最早的动状态的这个状态机模型,到motion machine,到最近大家看到的这种基于学习的,各种运动的生成方法,其实代表了这个基于状态,基于这个橘子,就是基于运动学方法的一个。
这么长时间的这么一个一个一个发展过程,然后呢实际上今年继最近一段时间,我们看到的,包括从这个基于强化学习啊,的这种大量的比较容易去训练很复杂的动作,这样的一些技术,包括我们这2年大家也是。
包括我们我们这边也包括这个很多研究,很多这个研究这些大学啊,还有一些研究机构提出了各种方法,就是可以做这种可控的运动,控制是这样生成,它其实是给带来一些新的一种。
我其实个人是觉得这些其实带来一种新的一个,新的一种可能性啊,就是我们前面一不断的提到物理动画啊,我们总是说物理动画是说是一,是未来的动画技术,它可以完全代替,我们这个就是关键帧的这一类的方法。
包括我们这个基于运动学的这个方法,因为它可以提供更真实的这样的一个体现,那当然我们前面也提到了,因为这个运动控制上的难度,这个可可编辑的难度,可可这个呃这种风格化的这个难度。
其实都会给我们带来很大的这个,这个实际应用的挑战,但是近2年的发展其实也是让我们看到诶,好像这个方法真的是有可能,在一定在比较近的时间内能够使用,在我们查这个真正的这个,这个工业场景里面去了。
这是一个非常非常有意思的,一个非常有可能的一个方向,那当然我们前面提到了这个学习,大家学习的时候,很多就是我们现在角色大部分情况下,我们还是去一个动作,一个动作的去学一个新的动作。
那当然我虽然随着我们这个基于学习,就是这种生成模型啊,运动生成模型的控制,生成模型这一类的这个方这些技术的发展呢,其实大家也开始变得,我们可能我们以后就不再学一个动作。
那这个其实我们可以进一步的扩大化啊,其实现在大家讲比如像是图像啊,或者是像是音频加语音啊,我们其实可以看到大量的这种,大规模的预训练模型啊,它可以在dancing task上。
在我们的下游任务上完成更好的一些一些操作,一些这个效果,但是对于运动来说呢,相对来说特别是对控制运动控制来说,我们其实现在另外一个非常有意思的一个,一个一个能一个未来,就是近未来可能很快就会有人做的。
就这样一个方向,就是说我们是不是有可能,从大量的这个运动控制里边,能够学习一个这种大部分的预训练模型,有点像人的小脑一样,就说因为大脑人知道,人的大脑是用来做认知的啊,做一些高级的决策功能。
但是人的移动啊,协调全身的动作很多时候是来自于小脑,那实际上我们可以大概说,我们其实可以,是不是有可能把这些所有的大量动作合在一起,构成一个人工的这样一个小脑的一个功能,它为我们更高级的这种人工智能。
来提供一个可移动的这样的能力啊,这其实是非常有意思的一个一个一个一个方向,另外呢就是说包括我们今天也看到了,就是这种跨模态的学习和生成啊,其实这也是非常有意思的一个1米特一些方向。
包括这2年啊最近非常火的这个chat gp d啊,其实大家可以玩,可以试着尝试一下这个chat jb,他其实可以给我们带来一些非常不一样的,这样的,就非常以前完全想不到的,一些这种这种这种特性啊。
就是说实际上比如说语言,通过大量的语言进行学习,我们比如说我可以做聊天,但是聊天这其实相当于是有点大材小用了,就是实际上你会发现,它里边会隐含了很多新的知识啊,隐含了很多这种语言里可以挖掘出来的知识。
那这些知识其实作为一个新的模态啊,它可能给我们在运动生成的时候,可以帮助我们去做一些事情啊,当然最直接的应用可能就是说我可以,是不是有可能通过这种语言模型和这种音乐啊,外就是声音啊。
各种跨模态的这种共同学习,能够让我们得真的去生成一个这种啊,属于数字演员啊,就是真正的数字演员不是那种皮套人,而是完全是靠比如语言,或者说这种某些任务驱动啊,它能够自动做出合适的动作。
然后通过仿真能够驱动环境做出,更做出非常敏真的这样的交互啊,这也是一个非常有意思的一些方向,当然还有一些其他的,就我们这里其实就放了一些空白了,其实可以有很多很多可以想的,就是在动画方面。
我们其实有这些技术,新的技术之后,我们可以做什么事情,当然还有一些这个像是一些基础的一些问题啊,包括比如说我们前面一直做的决动画,通常来讲我们做仿真的时候,我们都是用这种关节力矩来控制啊。
当然但是针对于真的人来说,你通常是通过肌肉来控制,你,不是你,因为人是不可能产生关节力矩的,你都总是通过肌肉收缩来进行控制,当然我们其实特别是对一些更加,要求精度的场合,这些其实还是蛮重要的。
就是我们是不是能够通过更复杂的这样一个,肌肉的一个方针,实现更真实的人的动作,那另外还有其他的一些相关的领域,比如说crowd simulation,我们其实基本game相关。
因为时间关系我们其实没有涉及到,就是像这种大型的人群啊,大家可以想象一下,比如说春运啊这种这种人群的互相互相移动,然后其实也不一定人群有可能是像比如少数人,比如两个人合作,比如摔跤。
然后比如说这个我们要合作,比如说我们要把这个家具装起来,那整个这个过程中,人的行为该怎么生成啊,该怎么去建模,这些其实都是一些非常好玩的,一些一些一些方向和领域。
ok然后那其实这也是最后我们这个这节课的,这门课的最后一页ppt了啊,我们也是非常今天呢今天到今天为止呢,就是我们所这个game 4105啊,所涉及到的这个所有的内容啊,但是其实整体来说可能有些部分呢。
这个轻重缓急啊,你开始预想的不太一样啊,包括这个内容的这个,实际上我会发现这个其实想讲的有很多啊,其实还是有相当的一部分这个没能完全讲到,当然我也希望这个大家能够在这个学习过程中,也是多少有一些收获啊。
然后这个另外一方面呢,也是这个再去借用一下,我们这个颜林奇老师的这样一个精华,经典的那个金名言啊,这个常看常新啊,就是虽然说我们这个课程到此为止了,但是呢也欢迎大家多多去,你可以回那个回顾一下,然后呢。
也是希望大家能够继续在我们这个微信群啊,不是这个qq群里面和各种方式,我们可以进一步的交流和讨论好的,那以上就是我们今天的主要内容啊,啊也是希望在将来能够再跟大家进行交流啊,那我们今天就到此为止。
GAMES105-计算机角色动画基础 - P2:Lecture02 Math Background - GAMES-Webinar - BV1GG4y1p7fF
啊那看起来没有什么问题的话,那我们就开始上,今天就开始上课,ok对我突然看了一下上次这个录的视频啊,就是其实我发现很多同学这个有有一个建议啊,好像是上周我们视频里的这个啊,就是我放的那个视频。
就是p p t里面是用好声音太大了,所以说加上我这个话筒声音不是太不是太理想,所以说可能有些同学在那个放视频的时候,会好像好像受到了一定的惊吓,这个这个这个这个我只能说很抱歉啊,这个下次我会注意一点嗯。
那当然今天这个我可以保证的是我们今天的啊pp里边是没有视频的,所以大家可以放心的把声音调大一点,因为我发现我的这个话筒好像调到最大,也就是这样一个状态了啊,所以说大家如果实在听不清呢。
可以这个把那个声音调大一点啊,然后那个等我们上传视频的时候,我再试试想办法去把那个整个视频的声音再去调整一下,ok那我们开始今天的这个课程,当然今天实际上我们按照大纲的话。
一个部分是这个动画里边的数学的background,然后另外一部分会简单讲一点关于浅项运动学,角色前向运动学的这个内容啊,当然这个我其实做这个准备ppt的时候也是做了一些调整啊。
然后也是觉得这个数学的部分还是比较多的,然后呢我觉得还是把这个极限运动学的部分跟放到下节课,就是跟我们这个逆向运动学放在一块讲,整体来说这个也是更加完整一些,所以说我们今天的主要内容啊。
其实是首先是一个对线性代数的一个简要的回顾,那当然我们不会回顾这所有线性代数中的部分呢,我们只会简单的回顾一下,就是跟我们这个角色动角色动画相关的一些内容,另外一部分呢其实可能是比较重要的一部分。
就是说我们会比较详细的讲一讲这个在动画里边,或者其实在图形学里,in general图形学里边用到的这个三维旋转的不同的这种表达方式啊,其实回字有四种写法,其实这种常用的三维旋转其实也至少有四种。
其实还有更多一些,我们可能有时间的时候,也会在更多的介绍一些,ok那我们就是回到我们的这个线性代数的基础部分,那这块的话我们会稍微过得快一点,因为属于大家都比较熟悉的部分,但是如果大家对这不熟悉呢。
那我其实也是建议大家这个我就再去翻一翻书啊,这个应该是这个大学1年级上半年就开始讲一些内容嗯,那当然为什么我们还要会讲一下,这也是因为就是这门课本身。
我希望还是能够把它变成一个所谓的这个self content,就是我们所有的内容都可以在这个ppt上找到,那当然我们也前面一部分有一些ppt呢,也是这个就是参考了game 201和game 103。
就是这个颜林奇老师和王浩敏老师的这个非常好的一个课件,ok那我觉得实际上最关最基本的一个概念吧,从线性代数里面概念,因为线性代数我们学的是什么,我们其实叫线性代数使用,我们学的都是线性空间里的各种量。
那这里边其实最基本的一个量就是vector,就是向量,那对于我们来说就是一般来通常的定义就是说向量是什么,向量是一个同时具有大小和方向的量,那当然在我们这个这门课里边。
我们会用这个粗体字来表示一个向量啊,那当然这个向量的长度或者向量的膜或者向量的这个大小,还是用这样一个这个这个双双线的符号来表示,那向量的方向其实也是在我们可以对应一个限量进行正啊,normalize。
对它进行这个归化来得到它的这个向量的方向,那当然对于向量来说,我们其实有一些特殊的向量,就是它的模等于零的时候,它是一个所谓的单位向量,那当然如果大家发现我ppt里边,比如说有些这个项链没有标出。
大家就是这个就理解一下,因为我这个也比较多了,有时候可能确实会确实会容易忘掉,那向量其实在图形学里其实可以表示很多东西,其实不只是图形学,那首先现在我们可以用来表示一个位置,我们可以用来表示一个速度。
我们也可以用来表示一些其他的一些更高维的特征,比如说运动的一些啊,比如神经网络,我们可以提取的一些英雄特征等等等等,那这里面其实向量本身我们并没有要求它是一个,比如说是不一定是一个三维的量。
它也可以是一个可以是个高温的量,那当然这里其实通常来讲我们讲用向量来表示位置的时候,我们其实还是假定了一个事情,我们是假定这个这个向量本身代表了从一个坐标的坐标系的原点。
指向这个点的这样一个这样一个向量的值,那当然向量其实有些一些基本的这个加减法运算了,大家都知道的这个两个向量相加呢,其实就是沿两个向量的方向分别移动一下呢,得到一个新向量呢,就是两个相加相加的值。
那当然向量本身是满足这个交换率的,就是a加b和b加a其实是得到的值是相等的,那类似的我们可以对向量进行数乘,那其实就相当于把向量的长度增加一些,然后以及可以更加复杂的复合的各种呃计算。
我们可以竖成一个各加减法合在一起,那在我们通常来讲,我们一个向量可以表示成一个啊一组数,就是一个一个数的一个一个一个数组,那对于我们这里来说,我们其实会把向量表示成一个列向量。
反正就是一个一个一个列的这样一个数字,那在这种表示情况下,当然对于一个n维向来说,那其实里面就n个数,从a一到a n,那对应的它的这个长度或者它的膜。
其实就是每一个每一个组成圆的平方的一个平方和再开根号,那当然实际上在对于三维来说,实际上我们可以这三个数其实就代表了在这个三维笛卡尔坐标系下的,这个坐标值啊,其实呢这样的话其实我们也可以很容易写出来。
对于三维一个三维点或者对一个三维向量,那我们可以找到它的位置或者找它的长度,那当然我们这个很多时候我们也去,虽然说有些时候写a x a y和ac,但我们就是经常也是会把它写成a1 a2 a3 啊。
来代表x和y和z这三个三个轴的这个这个坐标,当然在这样一个坐标的表示之下,我们前面的对于向量的计算,我们可以很容易地写成对于向量里边每一个啊,每一个分量的这这这种加减乘除的运算,但对线来说。
我们其实可以定义一些其他的运算,比如说点乘,其实我觉得点乘这个定义还是比较容易想到的,因为你想如果两个两个向量分别是有n个元素,那么除了前面的加减乘除运算以外,那么很自然的会想到一个运算。
就是说我会把两个向量分别对应那一啊那一个分量把它相乘,然后再加起来,那这其实也是也是这个所谓的这个点乘的定义,那点成为我们通常也是可以也会把它叫做内积或者叫叫标量级,因为它乘出来的结果是一个标量。
那同样我们大家从这个新代数也,是了解到这个点乘实际上会何为,这个首先满足这个交换率啊,同时也满足集合力量,然后另外还有就是点乘的每个向量对于他自己的点乘,其实得到的是它的这个模长的平方。
当然对于这个在欧式空间,其实通常来讲,这个这个点乘具体代表什么含义,其实不是太容易这个说明,但是对于欧式空间,就是欧式空间,就是我们平时这个遇到的这个三维空间,二维空间或者更高为扩展的这样一个空间。
在欧式空间里边,其实点向量的点乘它的几何含义,实际就是代表了这两个向量之间的角度的关系,特别是来说时间,就是说比如说a的a乘b a和b的点乘,那么他的所得的值其实是他们俩各自的长度的基因。
然后乘以它们俩夹角的这个coser,那这个其实是通常来说我们会用它来去寻找两个向量之间的这个啊,这个角度,其实我们刚才也提到了,因为一个向量可以表示一个高维的一个特征,那比如说我们很多时候。
比如说想想要做一些像是风格转换,那我们其实就是一个非常重要的一个特点,就是非常重要的一个问题,就是说我们如何来用一个把风格描述成一个高维的向量,那我们在做风格迁移的时候。
实际上我们是想要让迁移出来那个动作,它所生成的这个特征向量跟我们某一个以动作的分隔线缆,这个尽可能的接近,这个接近,其实也是用这个用这个内积或者他们俩之间的夹角来进行衡量,那当然有这样的定义之后呢。
我们其实计算这个夹角就是比较容易的,就是他们俩的点乘,当然我们要特别注意的是夹角其实我们是要求他应该是一个单位向量,那我们其实可以把每个向量进行这个单位化。
然后再去算一下这个它的这个cos 2 cos的值,那对应的如果a和b是垂直的,那其实对应的它那个点点击也是零,那他cos theta也是零,那同样的我们其实也是就是点成了另外一个含义。
也是我们可以找到其中一个向量在另外一个向量方向上的投影啊,比如说a在b方向的这个投影值其实就是a点乘b的方向,那就b的方向是什么,b就是b的方向,就是b除以b的这个模长,得到的就是这样一个方式。
类似的b在a方向的投影也是可以这样计算的,那其实有点成也相关的一个这个物理量,就是所谓的这个差成,当然跟点称不太一样,就是说因为点击我们是可以定义在任何任意高的维度上。
而插成其实差成一个will def,差乘时间就只只考虑三维,那剩下很多时候我们就是很多问题,就是说我们偶尔会遇到一些情况,我们可以把三维的这个叉乘的定义去扩展到更高维度,但是很多大部分情况下。
当我们需要用的时候,它其实就是三维向量之间的差乘,那当然现在的差乘有好几种定义了,其中一种定义就是说我直接写成这样的一个component,就是这个分量的这个乘积,然后做差这样的形式。
就是当时看起来是非常非常这个没有什么规律啊,但是就是还是有规律的,但是只要说可能一眼看上去感觉比较乱,那这个其实我一般来说还是会有一种比较简单的技法啊,就是因为我们把它因为插成出来的是一个向量。
然后向量的每一个分量,比如说x分量,那它对应的这个就是每一个项,其实都是以就是两项的两个乘积的差的形式,那对于x分量的这两项分别就是y和z的分量做乘积,然后做差,然后对y一行,那对应的就是z和x。
其实它对应的是x y z z和x z x y这样,的一个这样一个比较呃循环的这样一个顺序,这样其实也是比较容易记的,那当然另外一种定义向量的方式,就是说我们知道两个向量的啊,定定义这个插成的方式啊。
就是两个向量的叉乘,那其实它生成了一个新的向量,这个向量是跟前面两个向量都垂直,然后同时这个新的向量的方向是由这个右手定则来决定,比如说我从呃。
比如说a差b a差成b那么这个从我用右手从a向b的方向抓过去,然后大拇指指的方向就是这个生成它得到了这个结果的方向,当然虽然说这是一种,定义了就是它其实也是代表了这个加量差成的一些几何的特征。
那当然这里其实有一个问题啊,我其实个人觉得其实这个定义反而是不是那么直观,因为这里边你看还出现了cos,还出现了sn,还出现了三角函数啊,这个其实是挺容易想到的一个一个定义。
其实这个关于这个插成定义是怎么来的,我其实还稍微查了一查,但是我比如说这个维基百科上其实提到了,就是说差成实际上是四元数运算的一个副产物,就是这个哈密顿当年发发明四元数运算的时候,他发现里面有个差成。
然,后这个这个这个这个运算结果会把后来被单独拿出来,然后变成了一个专门的一个定义,当然这个是不是最早的,我其实也不知道了,但是大家如果有了解更多的话,也欢迎这个可以在我们这个群里啊。
或者在哪可以可以可以发给,但不管怎么样,我觉得从定义来说,可能这样一个直接从分量去做定义的话,这个可能是感觉更加自然的一种方式,但不管怎么样,这两种方式就是差乘和叉乘的这个几何含义其实是一一对应的。
那当然差乘有它自己的一些这个运算规则,其中最基本的就,是差乘得到的结果是跟差成的两个量就是是是互相垂直的,那这其实也相当于得到了,比如说c点成a就是c是a h b的这个结果,那c点成a和b都是零。
然后另外一个是插成的,但是它是在交换了之后,它是符号是相反的,然后还有另外一个非常重要的,就是它是非常非常跟其他的一般预算很不相同的一点在于,差成是不满足分配率啊,不满足结合律的。
对不满足结合律由是a差成b差成c和先算a hb再算结果的差,c这个结方向是不一样的,所以说这是,一个不同的查证结果,那通常来讲我们会用这个插上做什么呢,其实非常重要,非常常用的一个应用。
就是说我们用叉乘来寻找与跟a和b都垂直的一个一个方向,或者来或者另外一个角度上,也是说我们其实是找,因为a和b是两条直线,两条向量,我们其实a和b是可以扩张成一个平面。
那我们其实可以用叉乘来找到这个平面,它的法线的放量,那当然其实我要写成这个,我其实想一想,a a a也就是方向的差生,那得到的应该也是个方向,当然这个是不对的,其实你要是仔细想一想。
因为那个插成插成的那个计算其实是是两个向量相差啊,趁这个长度相乘,然后还有一个sz的,所以实际上如果这么算的话,其实得到那个n并不是一个方向向量,所以说这个其实还是要特别注意一下。
有时候确实有时候脑袋不带脑,脑袋迷糊的时候很容易就搞错了,那正常来讲,我们做叉乘,我们要寻找一个方向向量的话,其实应该是a乘b的a a叉乘b,然后再对这个结果进行规划,但这里就有一个要求啊。
就是说a和b肯定是不能是零啊,首先它不能是零,其次a和b是不能平行,的为什么呢,因为如果a和b是平行,我们可以证明可以很容易证明这个它们的差乘的值啊是零,比如说当a b都不等,都不等于零的时候。
a叉b等于零,其实等价于是说a和b是平行的,a和b的平行是什么意思呢,就是a等于一个标量乘以b那这个标量可能是正的,也可能是负的,那当然插上有很多常见的应用啊,比如说一个非常遇到的一个经常遇到的问题啊。
就是说我们如何去找到一个旋转,其实这个在什么地,方经常会用到呢,比如说我们做一些,比如说我知道这个人的腿和脚的位置,然后我想知道他腿的这个比如他大腿的旋转多少,才能把这个腿转到那个地方。
这其实是经常遇到的一个问题,那当然这个问题其实实际上这个问题其实想想是多解的,并不是只有一个解,不是理论上来说,我们可以对这个a和b之间做一个角分角平分面,然后在理论上在这个评分面上,所有的方向。
所有的一个向量都是可以作为这个旋转轴,然后绕这轴一转就可以把a转到b的这个位置,其实可以最简单,的想一想,比如说这个位置是一个a和b的这个啊角角平分线,就是比如说是是这样一个轴a和b的角平。
大家可以看到鼠标了,我也可以看到a和b的角平分线,那这样的话实际上我可以验证这角平分线转180度,那时间就把a一当成b了,但实际上通常来讲我们想要的是什么,我们是想要找一个旋转最少的一种一种一种旋转。
能够把a选了b,那这种情况我们就需要用到叉乘和点乘,因为这个点点击a。b,它其实给我们的是说a和b之间的这个夹角,然后这个角其实是,我们所有能够做的旋转里面最小的一个角,那为了能够把a旋转到b。
那么其实可以把a。b做一个a和b做一个差乘,得到的这个方向就是我的旋转轴,有时候我把a到b能把a旋转到b的一个这样最小的一个旋转,就是把a叉b的这个方向作为旋转轴,然后旋转飞度。
那得到了这样一个两个旋转,那另外一个问题,就如果说我们知道一个啊向量a然后我想把它沿着某一个轴,这个轴是用u来表示,又是一个方向,沿着一个方向旋转飞,do,然后它旋转到了b,那在这种情况下,b应。
该是b是多少,但这个其实乍一想好像很难计算啊,就是不知道怎么算,但其实想一想,就我们这里其实也是不会做更多的这个证明,我们就直接用到一些结论,其实可以很容易地想到。
因为这个如果说我把a沿着这样u这样的一个旋转轴进行旋转,那么a所经过的轨迹肯定是在一个跟u垂直的一个平面上的,其实是这样的一个大概是这样的一个平面,那当然在这个平面上,实际上我转的这个角度。
就是这个a和b分别和这个u垂直线的这个夹角,那其实就是我这个u的一个旋转角度,那为了能够计算这个实际的这个a到b的位置,其实我们可以把这个这个位移做一个拆分。
就是可以想象就是我们可以把它a到b这样一个位移拆分成,首先沿着一个垂直于u的方向,同同时垂直于u和a的方向进行一些位移,然后再沿着同时垂直于这个u和刚才那个位移的方向再反了一个位移。
那么这个方向是怎么定义呢,一个方向前一个方向就是u差成a,那我得到的是一个其实大概是说是沿着这个这个这个这个里边这个圆,它的切线方向进行一个位移,然后另外就是说沿着这个切线相垂直的方向再做一个位移啊。
这这两个位移的方向一个是u差a这是切线方向,另外一个方向是这个u差成刚才这个切线得到一个新的方向,那这个方向也是跟u和这个同时垂直的,那其实我们可以把它写成u差乘u差乘a,因为这个v是等于u差a的。
那当然其实这里还是特别注意的是,因为这个东西是不满足结合律的,所以说我不能写成u x u再查a,因为u x u本身是零嘛,其实就不再是一个正常的值了,那当然这里其实我只是定义了方向。
那接下来其实问题是说我到底应该沿着两个方向移动多少,那我们其实可以把这个就把这个因为它这两个构成一个平面嘛,我可以把这东西直接画在平面上,就这里其实这个蓝色这条线。
这个a其实是a向量在这个平面上的一个投影,那类似的b其实也是在b向量在这个方向上投影,那这样v和t实际上是我需要走的这样一个长度,那这里有一个c下角时间是我这个整个这个旋转的转轴。
那这个其实就可以比较容易看出来了,就是说因为我们知道这个沿着垂直的方向,在这个中间这个加点是c的情况下,那我沿着垂直方向移动的距离,那应该就是啊这个这个线段的长度乘以coffee飞的。
当然这个线段的长度,因为它是在这个点上的,projection在这个投影的长度,这个投影的长度我们其实可以看到它其实是a和u夹角的sin值,然后乘上a的长度,其实他就是刚好就等于这个差乘的这个这个长度。
那同样的沿着这个方向移动的距离,其实这个前面这一小段这个距离是可以看到的,它其实是应该是a的长度,因为a b和b长度是相等的,这个这个长度乘以cos theta是得到了这一小段的距离。
那所以说我需要移动的距离就是一减去cos,然后乘以这个前面的一个系数,所以总的下来的话,我们其实可以很可以最终可以得到这样一个阶段,就是v移动的距离。
其实sin c的乘以u叉a那t的话移动的距离是一减去cos c的,然后加上这个方向,那整个把它放在一起,其实这就是罗德里格旋转公式,就是看起来很复杂,但实际上我们推一推,发现机制还是比较容易推出来的。
那其实最终我得到b和a是有这样的一个关系的,就是b的位置其实是a加上一个沿着切线方向的位移,位移的大小是三in sa,但是还要承担一乘上这个u和u差a的这样一个长度。
然后另外一个就是沿着这个垂直于切线方向再做一个位移,大概是得到这样一个公式,那当然我们前面提到了,就是说我们可以在一个把一个三维的一个点,或者三维的一个向量表示成一个三个坐标的形式。
那这里其实我们隐含的其实怎么呢,我们是把一个把一个其实我们是隐含的,我们定义了一组正交基,那就分别是沿着x轴方向和y轴方向以及z轴方向,那当然对于这个自费者来说,特别是其实我们是有这样一个作为蒸汽机。
我们是有一些基本的要求的,就首先每个机向量它的这个长度应该是一,同时这三个正交基它的每两组之间的差额点乘应该是因为互相垂直的,所以说它点成应该等于零,然后另外其实还有额外的一个限定,其实也是要求。
也也是这个右手系的一个基本要求,就是说x差成y等于z,那其实其实也是刚才那个循环规定,就是y x上z等于x等等等等,当然在这样的正交基表示之下,那我们其实知道一个向量。
它其实就是这一组正交基的一个线性组合,我们可以用这个那这个线性组合的系数,那其实就是我们的系,这就是啊就是我们这个向量的这个这个这个这个坐标值,那在这样一个定义之下呢,我们知道a。
b其实我们可以直接写成这个两个啊向量,这个就是坐标表示啊,就是两个向量的这个这个向量表示,然后进行点乘,那这个我们再把它展开之后,我们可以得到一些这个ex。一。
ex就是自自呃自己和自己做点击的这样一个组合,以及一些这个自己不跟自己做点击,就是x。y或者是y等于z这样的组合,那这里其实可以很容易的,因为前面我们有这样的定义,我们可以知道这个后面。
这一项其实它应该等于零,因为它是正交的,那直接就这样就直接得到了我们这个点乘的这个这个对应的公式,时间叉叉也是类似的,就是我们其实前面插成很多时候,其实我自己也是有好多人记不住,那技术怎么变怎么办呢。
就先推一遍啊,因为确实这个按照我们只要我们大概了解一下这个插成的基本规则,就是说这个满足分配率呃,但是不满足结合律不是满足对满,但是不满足结合律,然后以及这个x差自己差自己等于零。
然后这个x x y等于负的x y x x等于它就等于等于,z那其实我们可以最终得到的这个其实可以回到我们前面啊,所遇到的那个那个那个量,那个查找的公式,ok那前面讲的是向量。
那么还有另外一部分就是关于矩阵,其实我觉得现在可能跟很多人很多,这个因为我现在也在学校上课嘛,我发现跟这个现在的这个大一的新生有很已经开始有代沟了,每次我说矩阵,其实我想到的是什么,我想到黑客帝国。
但是发现这个现在这个大一的这个学生,因为都已经0304年出生,都没有看过黑客帝国,哎呀这确实有点代沟了,那当然这个矩阵这个黑客帝国这个电影还是挺不错的,大家可以建议还是有时间可以看一看。
当然矩阵并不是黑客帝国了,他也用了这个matrix这样一个名字,当矩阵我们其实在定义上来说就是一个二维的一个数组,那当然二维数组我们其实,就是就比如三维的一个三维的一个矩阵呢。
其实就是一个3x3的这样一个数组,那我们可以把它写成三个列向量,就是每一列我可以把它认为一个向量,那类似的我们可以把每一行也可以作为一个向量,那其实可以写成这样的形式。
那此外呢我们知道这个向量一个三三维的向量,一个n维的向量,它本身也是一个数组啊,sir它本身也是一个矩阵,只不过他的这个只有一列的这样的一个矩阵,那当然矩阵有一些我们就是有一些特殊的一些形式。
比如说这个单位阵,那就是对角线只有对角线上有元素,然后是一,然后以及像是对角阵,然后比如说对称阵,然后另外还有一个比较特,就我们也经常会遇到的,就是所谓的反对成整形式,大概是大概是这个样子。
就首先对角线上是零,然后其次就是次对角线和这个是互相,就是和他的对对对称的位置其实是取相反数的这样一个这样一个关系,当然矩阵有一些基本的运算了,其中比如说最基本的是这个transpose,就是转制。
其实就是把行和列做一个交换,或者把下标做一个交换,那对于这个特殊矩阵来说,因为前面三个对于这个其实都是对称针,那对称阵基本的这个性质就是转它的转置率。
它本身那对于反对战争这个skill symmetric就是他的转职,其实是它的相反数,这个是一个挺啊稍微不太一样的一个点,那矩阵的乘法是稍微有一点点复杂的,我们知道这个啊矩阵就是乘积的一举乘积。
它们两个矩阵的乘积肯定还有一个矩阵了,那这个矩阵里的每一个元素,其实是这个a矩阵的某一行和b证对应的列做点击,然后得到那个数其实会放到这个乘积矩阵的这样一个位置上,那矩阵有一些基本的计算性质。
也就是a b和b a做成分别做的是他俩这个得到的结果是不一样的啊,不同的矩阵,但是呢矩阵的乘法是满足这个结合律的,也就是a b c a乘b乘c,我可以先算任何一个。
然后除此之外转制对于矩阵来说是a乘b的转置,等于b的转置乘以a的转置,哎我发现这个其实我发现之前还面试过一个人,这个他居然连这个都都都都都会忘掉,也是也是比较不应该,然后对于矩阵来说。
我们可以定义它的逆,这个逆就是说如果两个矩阵的乘积是单位整,那么这两个矩阵互相为对方的逆,同样来说对于矩阵来说,a乘b这个g的逆等于b的逆,乘以a的逆,就当然它要求是a和b都是可逆的。
那这样矩阵的这样一个运算的情况下,我们其实可以很容易地把,比如说点成比如说这个差成我们可以写成矩阵形式,那点乘的矩阵形式,其实因为每一个向量我们都把它写成一个列向量。
那么它的点乘其实就是列向量的转置乘以另外一个列向量啊,类似的,因为这个点乘是可交换的,那么其实可以写成那个b啊,b的转置乘以a的这样一个形式,那对于这个叉乘来说,因为插成我们当时定义的时候。
它其实是一个g一减掉另外一个g,然后这一个向量的一个形式,那这个其实我们可以整理一下,我们是可以把它写成一个一个这样的一个矩阵,乘以这样乘以另外一个b的一个向量形式,这样一个形式。
前面这个矩阵其实可以很容易看到,它是有一个非常明显的一个结构化的特征,那它是一个反对真正那前面我们提到反对反对真正的一个结构,就是它的转置是它本身,那在这个结果我们其实经常会做一个简单的写。
就是简化了写,就是这个反对阵,我们可以因为它本身是a的三个,它本身是a的差乘所对应的法律,真正并且它里边的这个三个,因为这里是有三个呃非礼的量,这三个量是a的三,刚好是a的三个三个三个分量。
所以说我们可以用一个符号,但这个符号其实每个教材啊或者是课本其实肯定用的不太一样了,但是我们这里其实简化一些,就把用这样一个监控号,然后下下面有一个差,那不代表它是a的一个差乘矩阵这样的一个形式。
那当然在这个矩阵的形式下,比如说a叉乘b我们可以写成a的叉乘矩阵,乘以b得到这样一个形式,那类似的a叉乘b呃,呃先b差成c,然后再用a去查成那个结果,我们可以写成a的查成矩阵。
然后括号里边是b的长成矩阵,然后查成c,那其实还是可以的,因为是有考虑到这个矩阵是有结合律的,那它自然就等于a叉乘b乘c,我们可以写可以这样的一个运算,那其实预算也算实际。
我们可以写先算a的差生局乘以b的差乘值,再乘c再乘上c,那得得到这样的一个结果,那特别一个特特例,就是如果b跟a是相等的情况下,那么其实可以这样的一个运算,a叉乘a叉c。
那它其实等于a的差乘矩阵的平方乘以b,那这里其实大家可以想到,可能有些同学有些同学已经想到了一个问题啊,就是说其实我刚才也是提到了,差成其实是不满足这个结合率的。
也就是说那这里其实如果我算a差成b插成c,那他是是不是也是就是从前面这个这个这个推导来说,如果说因为差成矩阵是满足集合的啊,分分呃算结合律的,那是不是说a长成b长成c。
它也等于a的差乘矩阵乘以b的长成长成c呢,那当然这个乍一看好像好像是这么回事儿啊,但是你仔细想想其实是不对的,为什么呢,因为这个叉乘矩阵是代表了前面这东西作为一个向量的时候。
他写成矩阵形式对应的这个这个这样一个矩阵,所以实际上如果是a查成b插成a先查成b,然后结果他成长成c,它所对应的这个查成矩阵应该是什么呢,应该是hb得到一个向量,而这个向量再写长生就这样形式。
所以这个跟前面这个跟前面的这个这个这个值是其实不一样了,所以说其实这个并没有,就并没有说我们前面结合率是不对的啊,这个其实还是还是依然是不满足结合律的,那当然在这样一个拆成矩阵的这样定义之下呢。
那我们其实再回顾一下,我们刚才这个沿着一个轴就把一个向量沿着某一个轴旋转飞他脚,那这个过程实际上我们前面是它是表示成一个叉乘啊,和一个sign的一个形式,我们可以把它写成,把这个把这个矩阵提出来。
把这个叉乘写成矩阵,然后把这个整个这个a的这样一个位置给提出来,那么其实可以得到这样一个公式,那这个公式实际上还是这个罗德里格全战模式,难道只是写成一个矩阵形式了,或者再进一步的,如果说我们再说。
更清楚一点,其实它是一个旋转矩阵,它代表了什么呢,它是代表了我沿着空间里边任意一个轴,这个轴的方向是u,然后旋转一个角度sa,但这要求这个这个这个u本身是一个单位向量,然后在这样的情况下。
它所对应的旋转的旋转矩阵其实是可以用这样的公式来算出来,其实是这样子,其实这公式看起来挺复杂,但其实也是这么来,那这个矩阵我们其实还有一些特殊的矩阵,比如说这个最我们最常用的,我们这门课经常会用到。
就是所谓的这个正交阵,那这个这页ppt其实是他可能上过其他的课,可能会比较熟悉,当我们一般说正交战它带了它的定义,其实它的定义本身应该是下面这一列,就是说它的正交阵是什么,正阳镇是说呃,首先它的每一列。
它的这个所有列是互相正交的向量,构成正交的向量,那当然正交的时间每一行也是这样的向量,然后在这样一个定义之下,那么其实可以得到最下面这个这个性质,就是说这个正交阵它的转置乘以它自己是一个单位针。
或者再或者说就是这个正交阵它的逆等于它的转置,这是其实正交正一个非常常用的一个性质,然后另外一个就是说这个矩阵的一个运算就是求它的行列式,那这个具体行列式其实这个定义是比较复杂的。
当然这个可能我们这里就不做赘啊,不做这个更多的介绍了,我们只是对一些比如三维的这样一个这个矩阵,那它的行列是相对来说比较容易计算的,对于三维的矩阵呢,想列式来说,它其实因为行列式是一个数值。
是这个在这个矩阵上进行一系列运算得到这个数值,对于一个三维矩阵来说,这个元素的乘积的和,那其实这个得到这个值就是它的行列式,那行列式本身也有一些呃,非常常用它的性质,比如说单位间的行列式是一。
然后两个方矩阵的乘积,那它这个它乘积的行列式应该是等于每个行列式啊,每个啊矩阵的这个行列式的乘积,然后以及一些这个比如转制本身是转制和他自己的行列是相同的啊,然后以及逆的行列式等于行列式的逆。
那这对于我们这来说,其实有一个非常重要的一个性质,就是说一个正交正,它的行列式是正-1,他可能是正一,可能是-1,但是不可能两个都是了,就是我随便拿一个正交正,那它要么是一,要么是要么是-1。
但为什么什么时候正一,什么时候-1呢,这个取决于我的向量的顺序,也就是说实际上对于我们刚才提到的这个正交机,就是在满足这个右手定则的情况下,那它的这个先行列式应该是正义,那否则应该是-1。
然后另外就是说还是刚才回到了,就是这个这个插成我就插成,经常是有好一种方式来帮我帮人记忆,还是怎么怎么做的,其中另外有一种方式就是来把它用行列式的计算来来把它写出来。
其实我可以把这i j k就是它对应的是三个啊,xyz 3个轴上的这个正交基,那我可以把它写成一个3x3矩阵的形式,那么可以做一次,按照我们这个行列式的运算规则,那么其实可以得到前面同样的一个公式。
就是差成了每一个component,每个分量,分别是什么,那我们最后一个关于这个啊矩阵的一个性质,或者一个特这个这个这个运算就是它的特征值,那我们知道这个一个矩阵对于一个方阵来说。
如果说我们有一个非零的向量,它满足a乘以x等于lx,或者说a乘以x跟x是共线的,那么我们在这种情况下,我们知道这个lambda这个lamba是a的一个特征值,并且对应的x是这个a的这个特征特征向量。
那当然怎么算的,lana和ex的话,那我们大家这个我们就大家可以去找,去回忆一下当年这个新年代数的课本,其实对于一般的矩阵来,说其实算这个拉布拉和这个其实挺麻烦的,因为它需要经常会解一个高高于方程啊。
其实也就是说其实对于这个大于三阶的矩阵来说,基本手算是不大现实,除非这个矩阵本身是有一些是一个点赞,是一个有经过设计的这样一个这样一个形式,但对于我们来说,其实有一个结论是比较重要的。
就是对于一个3x3的正交阵来说,或者说其实不一定3x3的,或者对于任何一个鸡刺鸡刺的这样一个奇数阶的这个正交阵,那么它一定会至少有一个十的特征值,那这个特征值是什么呢,那这个增值它的它要么是一。
要么是-1,然后但这个正-1是就是跟他的这个这个行列式的值是相同的,这里是一个具体这个结论啊,但是这个具体证明我们这里就不就不展开了,其实也是很容易可以大家可以可以可以在那个信息代数书上找到。
ok那前面我们就再简单回顾了一下,我们需要用到的一些线性代数的基本知识,特别是这个向量和矩阵的一些基本运算,那我们接下来第二部分呢,我们来回顾一下关于这个transformation。
就是变换的一些一些内容,当然我们这里其实关注的主要还是刚性变换,那什么是变换呢,其实我们是了解其实变化就大概我们可以分成三种类型,一种飞行是平移,一种类型是旋转,还有另一种,还有另外一种类型是缩放。
其实我们所有的变化都是可以通过这三种子,就是单独的变换进行组合来完成,但这里,其实有一个问题,就是说平移和旋转是不会改变一个物体的形状和大小的,但是这个缩放,因为它顾名思义嘛。
它其实是会改变我这个形状的这个比例和大小等等,那对于我们一般的人来说,其实比如说我们动物啊,其实我们的骨骼是一个刚性的,我们在运动过程中,实际上我的胳膊是可以旋转的,可以平移的。
但是唯一就是不能不能缩放了,你让我给我发生缩放了,那估计是这个事故就比较大了,也许也许是也许是出车祸了等等等等,那所以说我们这里其实主要还是关心两个部分,一,个是这个平移和一个是旋转。
那当然其实缩放我们也是实际在定义上来,就是计算也是比较简单的,因为我们知道这个把一个物体沿着三个轴进行缩放,那其实它对应的这个运算等价于我把这个点这个向量乘以一个对角阵。
那对角阵上三个元素对应的是我的这个呃,在每一个轴上的缩放的这个这个大小,那对于平移来说,首先是非常简单的,因为它就是线性的,就是我如果说把一个物体把它加了一个平移,挪到另外一个位置上。
那这个物体上的点的位移啊,在新位置上,这个物体的,点的位呃,这个这个向量那其实就是它原来的向量加上这个平移哎,等于t那同样的,如果说我们有多个平移,得到一个新的位置,a撇撇a两撇,哈哈哈。
然后它这个其实这个得这个总的这样一个平移,其实是前面两个平移的一个和,这是平移的一个性质,因为平a非常简单,就是一个线性的,所以说我们其实也不用多,不用不用更多的进行讨论,那另外一个方向就是旋转的。
其实我觉得这个三维途径学故事,三维,动画其实我觉得很多时候大家搞不搞,搞不定的地方,其实主要还是旋转,因为旋转是非常讨厌的,因为首先它是一个非线性的东西,其次呢。
它这个他在这个这个这个就是这这这有限旋转和无限性和非常无限,小旋转,其实它的性质还不太一样,那当然旋转来说,比如说我就是直观来说,比如说我一个有一个box,有一个这个方块,我把它做了一个旋转。
那它这个方块上的一个点被就是被这个旋转带着走了,那这个得到一个新的位置,那这个为新的位置坐标和原来的位置坐标,其实它是可,以用一个旋啊,用一个旋转矩阵做这个矩阵乘法的了。
那其实是一个基本旋转的一个一个性质,那当然旋转矩阵有一些基本的性质了,首先旋转矩阵一定是一个正交阵,那满足正交阵的性质,也就是它的逆等于它的转置,然后同时它对于它的转置应该等于单位阵。
另外一个就是说作为正交阵,它的行列式要么是一,要么是-1,那对于这个旋转矩阵来说,它一定是正一,然后但其实这也是说明其实是旋转矩阵是不会改变,所以轴的顺序,另外就是说旋转矩阵本身是一个刚性变换,就是它。
是保持这个旋转前后的向量的长度的,就是r乘以x,它的模长应该等于x,这个其实也很容易证明了,因为把你把这个模长写成这个转置相乘的形式,其实可以很容易得到这个结论。
那另外一个就是说我们如果需要把两个旋转进行这个组合,就比如说我这个物体,我首先用r一来把它旋转,得到中间的这个这个这个形状,然后在终端形形状的基础之上,我再把它旋转r a2 ,然后得到一个总的旋转。
那这个总的旋转应该多少,那是等于r一乘以r吗,那这个显然是不对的,但是也不是,这么显然,但这个很多时候我们说他对或不对,可能就是很多时候是一个语言上的,基本上是一个阅读理解题,从我刚才这个描述来看。
其实r一乘以二是不对的,那应该是反过来,应该是r2 乘以r1 ,为什么呢,因为r2 的这个旋转是在r一旋转完之后进行的,所以说它其实是r2 要成叠加上r一的这个旋转的这个这个效果,所得到的是这样的一个。
所以说对于旋转来说,它的combination,它的这个组合时间就是旋转矩阵的乘积,那当然要注意一下顺序,那对于我们常用来这个旋转来说,我们,其实有一个最呃,因为我们这个这个对于一个正交值啊。
对一个比如三维空间来说,那其实我可以很容易地定义沿着坐标轴的旋转,那它是可以写成一个类似于这样的一个三角三角函数的一个形式,当然这里其实因为比如说沿着x轴旋转的话。
那其实旋转之后这个向量本身的x的坐标值是不会发生变化的,那对应的这个x这一项呢其实就是一,那其他那两项就是就是sin和cos的一些组合,那如用这样的一些基本的这个旋转矩阵。
那我们其实可以构,造更加复杂的一些旋转矩阵,比如说这里就是说我可以把一个还有一个方块,通过沿着x轴转60度,再沿y轴转45度,再沿z轴转72度,那就会得到一个新的一个位置。
其实是从这个位置转到下一个位置,所所需要经历的这样的一个一个旋转组合。
那当然其实我们前面这个旋转组合就是它虽然是做的很复杂了,做了三次旋转,首先转了60度,再转45度,再转72度,它的结果其实等价于什么呢,等价于我在我是沿着某另外一个旋转轴,就是这样一个u,但这个旋轴是。
计算出来的五沿这个这个轴转81度,它得到的这个旋转跟我前面这个转三次的,它旋转是完全相同的。
那这其实也是代表了什么问题,就是说诶不好意思,其实这个说一个这个旋转的一个旋转轴的概念,为什么我们刚才不断提到,我们会为什么会回顾到这个矩阵的特征值和特征向量呢,其实而且我们也提到了。
对于这个智能家政来说,它总会有一个特征向量是一啊,对于旋转矩阵,但是一但是一般矩阵可能有-1,那我们其实可以知道,至于因为对于特征向量是啊,特征值是e的,特征向量。
那它所对应的这个r比如u是一个向量的话,那这个r u一定等于u,也就是说明什么呢,说明这个向量或者这个方向在我们在旋转的过程中,它是不变的,所以这个不变量其实我就对刚好是对应于这个旋转的旋转轴。
所以说其实另换一种说法,就是说实际上这个旋转我们是可以把它认为是一个,就不管前面这个旋转是怎么来的,我可以转多少次,最终得到这个总的旋转,它总是可以表示成沿着一个坐标轴旋转一个角度这样的形式。
但这个坐标轴本身一定是这个旋转矩,阵的这个对应于特征值是等于一的这样一个特征向量,这是一个旋转矩阵,那当然一个问题就是说当我给了一个旋转矩阵之后,我该怎么去找一个这个旋转轴以及这个旋转角度。
但这也是很多方法了,其中一种方法就是可以简单推一推,比如说我们这r u乘以等于u那么其实因为这个r是旋转矩阵,所以它的逆就等于它的转置,那么其实可以把r的逆乘乘上两边,得到右边这个公式。
然后这两个东西这两个方向就是互交换一下位置,做个差,其实可以得到r减去rt乘以u等于零,这样一个形式,那r减r t a得到了这样一个这样一个矩阵,那这个矩阵我们已经很熟悉了,前面已经见到好多次了。
他是一个反对任,那我们知道一个反对称阵总是可以跟一个正啊差成建立关系,所以说其实我们可以把它写成一个差乘等形式,那我们知道两个两个向量叉乘等于零,那代表什么,代表如果是这样。
或者是在这两个向量都不等于零的情况下,这个差乘等于零,这件事情就代表了这两个向量是共线的,那这里其实u肯定是不等不等于零的,因为u在我们定义定义里边,它,应该是一个单位向量。
那这个u p如果在它不等于零的情况下,我们其实是可以认为是啊,就他跟u是同一个方向,那我们其实可以进一步的就是说从u撇,我们因为他们的u是从一个方向的,那么其实可以把对u对进行一个正加了单位化。
把它这个单位化之后能得到这个向量其实就是我们的旋转轴了,咱这有个要求,就是说u p必须是非零的,那什么时候是零呢,就是r和r就是旋转矩阵本身是一个对称阵的时候,它这个对应的优撇是零。
那学生组织什么时候是对称,真的,其实这,个旋律里面大部分大部分情况是不是对称,真的只有在一些特殊的情况,这个特殊情况就是说当我沿着某一个轴转了0度,那转0度其实它就是一个单位证了,或者转了180度。
那这个时候他其实得到的是一个对称轴,那大家自己可以验证一下,但这个结论其实我们也可以从前面的这个罗德里德公式,罗罗德里格公式可以也可以很容易地得到,因为我们知道前面已经推了半天,其实已经推到了。
如果说我沿着某一个轴优旋转c的角度,那我其实得到那个旋转矩阵应该是有这,样的一个形式,它前面这一半是一个反对,是反对称阵,后面这一半其实是一个对称针,那我其实可以很容易得到r加减掉r的转置。
那其实可以得到这样的一个形式,那同样呢我们其实可以进一步得到从这个r减去r的转置,我们可以得到两个sin对的,所以说实践可以得到这个u的,其实这个u的长度就是两倍的sin c的,那会进一步的话。
我们说c的是多少,那c的就是1/2这个长度,然后这个它的arc那个ark sign,ok那这其实我们可以得到一个旋转,这个,旋转轴和旋转角度,那这个基础之上呢也不是这个基础上。
就说我们其实是从另外一个角度来看啊,就是说实际上一个旋转它代表什么东西呢,就如果说一个一个方体,它被一个旋转r转到了现在这个状态,那么这个方体上正方体上一个坐标在原来的没有旋转的时候。
它这个坐标是x撇y撇c撇这样一个点在学生之后,就他在这个随着钢铁呃,这个这个立方体一块动的这样的一个局部的一个正交基的表示一下,它的表示还是不变的,它还是x撇y撇c撇,那当然这个点在于在整。
个世界坐标系,或者说在原在这个原来的这个标准,真压器的表示其实是x p发表和c表,因为他们的表示其实代表同一个向量嘛,所以它只是表示着这个方法不同,那所以我们其实可以得到这个可以把这个正压机。
这个把它写成一个矩阵,然后进行一个做一个做一个平移啊,再做一个这个这个这个这个球逆,那其实得到了就是我们旋转矩阵,或者说我们旋转矩阵代表了什么呢,我们旋转矩阵代表的是说从一个局部坐标系。
由这个随着物体一块动的这样一个局部坐标系,它上每一,个点的坐标值,把这个最高值转化到全局坐标系下的时候,所需要的就是全局坐标系的那个坐标值,和这个原来的坐标值的一个可能关系。
就是这样一个旋转矩阵来给出的,那如果说我们这个里边这个这是一个transformation,这是一个变换,它里边同时有旋转和平移,那这种这种情况下,我们其实可以我们做做作为变换。
其实从这个啊物体坐标系的一个点转移到全局坐标系的时候,我们其实是需要考虑到平移的过程,那他说反过来我们需要把一个点从一个全指标系转移到局部坐标系,那我需,要把那个点先减掉这个平移。
然后再乘上这个相应的这个啊旋转矩阵的逆就是就是就是它的转置,那这个关系其实是我们会后面会经常用到的,为什么呢,就是因为我们做的这个特别做前向动力学或逆向动力学啊,这个局部到全局或者全局到局部的转换。
而且实际上我们是在一个change一个链,就是一个一个骨骼,这个这个这个这个这个链式结构上进行做的,所以说实际上我们要不断要做很多次这样的转换,才能把一个点转换到,一个全局坐标系的表示。
好那我们到现在我们前面主要是回顾了一下关于线性啊,现代数以及我们坐标纸纸啊,以及这个这个变换或者刚性变换的一些一些内容,因为前面也提到三维旋转,其实是就是整个图形学或者是我们在动画里边非常麻烦的一个量。
因为主要原因是因为它是非线性的,那对于三维矩阵来说,三维旋转来说,实际上我们也是有很多呃,发明了很多不同的方法去表示它,就是说回字有四种写法,其实这个我自己找了找,其实第四种写法是比较难比较罕见的。
以至于好像好多这个这个这个字体都没有,只有宋体才有这个字,所以说这是但是我们这个只是用它来做一个做一个做一个做一个标记,那我们还是回到前面那个问题,就是我们前面一直提到旋转可以表示成一个正交矩阵的形式。
对于一个一般的矩阵,我们知道3x3的矩阵,它是一个它有九个元素,那对于这个郑家镇来说,因为郑家镇其实有额外的要求,他是要求呃矩阵本身乘以它的转置等于单位阵。
那实际上这样每一个这样其实是我把这个因为矩阵乘矩阵得到,是另外一个矩阵嘛,所以说这个美生成的矩阵也是一个3x3的矩阵,它是九个量,所以每一个量其实对应一个方程,那这个方程里边,那这些又代表什么。
代表实际上我们虽然有几个参数,是由其他参数来决定的,或者说再进一步的具体一点,就是说啊在这个正式一点,就是说这个我们的自由度,我们的degrees of freedom,它就是三。
那这个其实自由度就代表了,我需要多少个参数才能描述某一个某一个某一个物体或者某一个东西,那当然其实我们想想,其实前面还提到,我们还有一个另外的一个性质,就是说对于旋转相对来说,对于一个旋转矩阵来说。
我们还是要求它的特征值啊,sorry他的那个行列式应该是正义,而不是-1,那当然这个行列式这个事件并没有引入这个,虽然它引入了一些约束,但他只是说让我的解空间从两半变成了一半。
所以它其实并没有进一步的减小我的自由度,所以说这个我们整体的自由度还是散,当然我们这里还有另外一个问题,就除了前面这个啊啊这个这个向量的问题,我们其实我们经常在动画里边,我们还经常会遇到一个问题。
就是差值,就比如说对于一个平移的差值,比如说我在t0 时刻,我在零时刻的时候,我这个方块的位移是x0 ,我在一时刻的时候,方块的位移是x1 ,那我们其实经常会需要做什么事情呢,我们如果说我们只有这两针。
比如我们在动画里面只有这两帧的这个位置,那我们需要算一个补间动画,就是从从0~1这段时间内,我需要计算一下这个这个方块在哪里,那这个时候我们就需要用到差值,那对于这个平移的差值其实是比较简单的。
我们其实可以很容易用一个线性差值来进行实现的,那这个差值我们可以看到它有一些一些基本性质,首先对于任何一个t来说,x t肯定是一个合法的平移,其次呢对于这个线性差值来说,我们其实可以很容易地证明啊。
它的这个速度就对t的导数就是它的速度是一个常数,当然常数有些时候可能不是最好的,所以我们想要的,但是对于常数,如果他能是常数,其实说明至少我们是可控的,所以这是这个对于这个平移的差值的一些这个特点。
那类似的,比如说我们有两个旋转,我在这一时刻它的旋转是二零,在啊在零时刻旋转是r0 ,然后在一时刻它的旋转是r1 ,那这种情况下,我们其实也是需要做一个差值,但这个差值就更加复杂一点。
就这个差值也是说我们对于t时刻在零和10~1之间的一个t时刻,我们想要去计算一个合适的这个旋转,然后这个旋转刚好是r0 和r一中间,这个二零旋转和r一旋转中间的某一个值,当然这个。
时候我们会发现线性差值就就大概是不work的时间,我们试了一下,它就是不word,我们可以举一个非常简单的例子,就是说比如说我们可以写一个旋转矩阵,是沿着y轴旋转-90度。
那大家如果其实回忆一下刚才我们那个三个基本旋转矩阵的那个公式,那它写成是大概是这样一个形式,那对角线它就是一个不是调夹,是在这个另外一个对角线上的一个一个一个矩阵,那同样的。
如果说我们把这个r一是一个沿着y轴旋转正90度,那其实对应的这样一个矩阵,其实可以发现这两个,矩阵其实刚好是反对称的,所以在这种情况下,如果我们直接对这个矩阵的这个单位进行差值,会发现一个什么事情呢。
就是比如我们取0。5,那会我们会发现0。5的两个的差值刚好是等于这么一个矩阵,那这个矩阵首先他肯定不是一个,它肯定不是一个正交阵了,而且是就是你就可以看到,其实他因为零零非常多嘛。
它本身其实是个不可逆的了,所以都不用去提这个正交阵的问题,所以实际上如果说我们用线性差值去旋转,用差值出来得到这个矩阵乘以这个这个这个这个box,这个立方体的话,你会发现这个地方体它会一边转一边压扁。
因为本质上来说,这个这个矩阵其实就是一个缩放矩阵,而且其实是在x和z方向缩放,是缩放是零,那其实它就是会会会压扁成一根,应该是会压扁成一根线,然后再再又呃放开变成一个变成一个矩阵来变成一个正方体。
所以这个其实就不是一个非常好的一个一个差值的形式了,那么其实我就说到这件事,就是回到了我们什么样的一个差值方法是一个好的插值方法,那首先我们是希望这个差值的这个过程在每一时刻。
都应该得到的是一个合法的旋转,那当然许攸没有什么表示了,他可能是一个不同的这个合法形式,合法的定义是不同的,但是我们希望它的每一时刻都是合法的,就不会出现我这个转着转着这个就就就变形了。
然后又变回来这种问题,另外一个就是我们也还是希望这个旋转,它是比较以一个定啊常数的一个旋转速度来进行完成的,就这个差值也是最后最好不要说,比如前面转的快,中间转的慢,然后后面又转得快啊。
这其实是一个不太好的现象,就虽然还是那句话,虽然说常数不一,定是最好的,但至少它是可控的,就说明我们想要实现某些效果的时候,会更容易实现一些,那这样我也回顾一下。
对于一个直接用旋转矩阵来啊来表达一个旋转的,这个其实有很多问题,首先这个旋转矩阵本身是很难构造的,因为它是首先它有九个九个完全没有什么意义的参数,就不能没有直观意义的参数,其次在构造过程中。
我们还是要求它是一个啊,要是一个正交阵,那其实我们每调一个参数,其实我其他的参数也要相应的变化,所以整个来说构造起来是比较有难度的,当然对于,旋转角来说。
我我把这个旋转矩用这个旋转矩阵的表示去旋转一个向量,那是非常容易的,因为本质上旋转就这么定义的,就是矩阵乘以向量就得到了一个旋转,另外一个就是这个用旋转矩阵直接进行这个旋转的差值是不太容易的。
至少线性差值是没有什么好办法可以把它插的比较呃,比较漂亮的,所以这是旋转矩阵的一个基本一些基本问题,但实际上后来我们很多这其他的几种啊旋转的表达方式,其实都是在去解决这个旋转矩阵这个问题。
就是旋转表示的一些问题,比如最常,用的一个就是所谓的欧拉角,我们刚才也提到了,其实对于我们三维旋转,我们可以定义一个所谓的基本旋转,就是沿着x y z3 个坐标轴分别的这个旋转。
这个旋转矩阵我们可以很容易很容易的把它写出来。
那其实可以证明就是说任何一个旋转,我们都是可以把它表示成三个三个不同的这个基本旋转的乘积,或者说其实刚才我们已经举过这个例子,就是说我们要实现从上面一个方块选择下面的方块这样一个旋转。
我们其实可以通过沿着x轴转60度,再沿着y轴转45度,再沿着z轴转72度这样一个方式来实现这个旋转。
那当然实际上这个旋转的这个方式是有很多种,实际上对于欧拉好拉角来说,实际上它是允许任何一种,其中不是连着两次沿着一个方向旋转就可以了,就什么意思,就是我连着我不能先转x再转x,然后再转z。
那这其实我前面两次转x是,其实等价也是一次一次旋转,所以在这样的一个约束之下,实际上我们可以找到12种不同的旋转方式,比如最常用的x y z,然后x y这个y减,x等等。
然后它其实也是允许问我在这个过程中绕着某一个周转两次,比如说绕着x转两次,但是这里要求是啊,这两次旋转中间要隔着另外一个轴,那所以说刚才那个旋转我们先沿着x转60度,再沿着y转45度,再沿着z转72度。
那我们其实可以等价的变成了先沿着z转42路,然后沿着y转4度,然后再沿着x转转62度,当然欧拉角其实有一个问题是什么呢。
就是说实际上好像很多人就是很多不同的地方,不同软件它可能会follow不同的convention,就可能有不同的这个对,于jo呼拉角定义,因为我们前面提到,比如说先沿着x轴转多少,再沿着y轴转多少度。
我们沿着到底沿着哪一个x轴,因为这里随着物体的旋转,其实它也会它,因为一开始物体它的x y z,它局部的x y z的轴跟世界坐标是重合的,但是随着我的旋转,这两个就变得不重合起来,随着对奥拉甲来说。
实际上我们常用的也不是常,它就就就就有两种convention,一种是说我是在每次旋转的时候沿着那个旋转轴,这个旋转轴是物体局部的旋转轴,比如说比如说我先着,先沿着x转,再沿着y转,再沿着z转。
其实对于左边这个视频来说,它其实是每次都是在这个局部坐标系,你可以看到这个这个旋转的方向,然后另外一种就是所谓的这个定固定固定旋转轴模块叫ring rtation,其实是一样的,就它是每次旋转。
当我当我说沿着某个轴旋转的时候,实际上我是沿着世界坐标系的某一个轴旋转,那这其实我也是同样的做了一个先沿着x轴旋转,再沿着y轴旋转,再沿着z轴旋转,让大家看到第一次做x轴旋转的时候。
它其实是因为两个轴重合,所以它其实旋转是,相同的方向,但是沿着y和z旋转的时候,它其实是并没有沿着这个里边这个小的这个小坐标轴,它的旋转进行这个它的嘴巴轴进行旋转,而是沿着这个世界坐标系的这个旋转进行。
当然对于这两种方法,其实它旋转的效果其实是就是说我们都同样还是能实现相同的,这个就还是能实现所有的这种这种旋转的表达,那对于这种第一种就是当我比如说先沿着x再沿着y,再沿着z进行旋转,诶这是不是写反了。
哦对没错,就是先进的x再沿着y z沿着这z旋转,它所对那个旋转矩阵其实是rx乘以r y乘以r z这样的顺序,然后对于右边这种它是反过来的,其实回想一下我们前面那个combination。
就是那个旋转组合的时候,就是我们那个r为什么是r乘r1 ,而不是r一乘r2 ,所以这个地方其实对于这个固定的旋转轴,固定的实际坐标系的旋转轴,实际上当我说沿着x轴转,再沿着y轴转,再沿着z轴转。
那时候他所做的这个顺序其实是rz乘以r y乘以rx,所以大家有时候在看到一些软件的时候,比如说玛雅,比如说玛雅,其实就是说它的x y z是指的是前面这种,然后unity unity其实有点怪啊。
就unity其实你是当你它有一个选项了,就是你可以选local或者global,那对应的是一个固定坐标轴,或者是一个随随物体动的这样一个旋转轴,那当然unity本身的x y和z就是你看到它的unity。
比如说我去调一个物体的这个奥拉角x y z,其实那个xyz并不是x y z这样的顺序,如果没记错的话,他好像是y y x z的这个顺序,就是这个其实也是要注意一点的。
是a real是啥样,我就不知道了,因为我不太熟,当然这个欧拉角其实有一个非常重要的问题,就是所谓的这个万向锁,这个万向锁其实就说因为我们三个轴可是随着物体进行转的嘛。
那么其实在某一个方向上其实会出现一个什么问题呢,就是这两个旋转其中两个旋转轴会贡献,那在贡献的情况下会出现什么问题,就是说我们会丢失一个自由度,就是其实这两个图都是那个维基百科上这个这个摘下来的。
其实右边这个就是一个万象万象锁的一个例子,就是在这个半箱锁的情况下,其实如果说我这个飞机想要让它这个顶上,那个方向进行自转,你会发现它是转不了的,因为这个时候他缺少一个自由度,但本质上来说。
万象所只是在这个只是我我想要真的去动它的时候,才需要有才有这个东西,就实际上如果说我真要让这个飞机这个在外面旋转,我们可以是确实可以直接加一个全局的一个一个一个旋转矩阵上去,那他还是能够转的。
他只是在当前这个机械铁战线还是转不了的,那就是另外一个角度,就是说万向锁会带来什么问题呢,因为它有两个轴是重合的贡献的,那么就意味着什么呢,在这种表示之下。
这两个轴只要这两个轴它们的这个旋转角的和或者插满足某一个量,就可以实现这个旋转,而这两个轴本身是赚这个数值是多少,其实是可以随意变的,那这大概是什么问题呢,就是说实际上在这一瞬间。
我的这个旋转的表示是不唯一的,就它还不是那种x2 派的,是相同的这种不位移,而是它可以是随便一个值,这种这种不为一,那其实也是带来什么问题,就是说当我们去把一个矩阵,把它转成一个欧拉角表示的时候。
你会发现在这个地方它会碰到一个齐一点,所以说这个是就是其实也会带来一个表示上的问题,这是一个跟blog就是万象解锁的一个茂名,所以回顾一下欧拉角其实是我们最常用的一种,或者实际上就是在我们大部分软件里。
其实我们去调一个物体的这个旋转,基本来说都是极优拉角的,那当然我们欧拉角因为我们知道它一个旋转我们至少需要三个两,那其实我俩就刚好有三个参数来进行表示,那跟王老角当我们只定义角是不够的。
我们其实还要定义是每个角度它所对应的这个旋转顺序,对欧拉角来说,我们其实有12种不同的旋转顺序,以及两种不同的convention,然后这是这个欧拉角的定义,当然对于欧拉角来说。
首先我们是比较容易去用拉角来实现一个旋转的,特别是我们其实可以很容易地在那个ui界面里去进行调整,另外来说实际上欧拉角,因为它刚好每个欧拉角都是对应一个沿着某一个坐标轴的旋转。
所以说我们其实把它用这个欧拉角去旋转一个物体啊,算去旋转一个向量,相对来说也是比较容易的,当然我需要做三次这个这个矩阵乘法,那另外一个问题,就是说我们可以很容易地在欧拉角的表示之间去做这个差值。
我就直接三个三个坐标值进行差值,就就就做线性差值就可以了,那当然这个当然首先是这个差值本身是可以保证我生成的这个旋转,还是一个合理的旋转,因为他还是一个,因为奥拉教理论来说。
这三个角的取值是这个可以是这个正正负无穷,都是在这个实数集上取值,那哪有一个问题,就是说我们在做差值的时候,还是需要去处理所谓的基点问题,基点问题是什么呢。
就是因为欧拉角它是来自于三个对三个这个旋转轴对三个分量的旋转,所以说实际上我们可以看到这个啊,比如说阿尔法加上阿派还是对应的相同的旋转,也就是说对对这个旋转来说,我们至少阿尔法和阿尔法加阿派加。
或者阿尔法加2n派都是相同的旋转,那这个时候你做差值的时候要特别小心一点,因为有些时候比如说一个人他在不断的这个原地打转,他转一圈之后,你会发现你做差值的时候尾,其实你如果处理不好的话。
你会发现你的人在转转转的时候,他突然就反向转了一圈,然后再继续转下去,这是为什么呢,就是因为欧拉角在你在某一时刻,比如它是大于大于零,接近于pad,但是在某一车它超过派了之后。
它的表示可能会直接变成了复牌,那你如果在直接在派和复派之间做一个差值,你会发现这个人就瞬间反着转转了一圈,然后再继续往前走,所以你的差值的时候需要处理一下这个问题,而另外一个问题就是说。
欧拉角它其实有一个所谓的这个万向锁的一个问题,那除了欧拉角以外,另外的还有一些,还有一种就是常用的这个常见的,毕竟是常用的,常见的这个旋转表示就是旋转矩阵啊,sorry轴角表示或者叫其实对应的也是。
其实也是对应于这个旋转向量的这样一个表示,我们刚才其实已经提到了,就是任何一个旋转,我们总是可以把它变成可以把它分解成,或者把它提取出一个旋转轴和一个旋转角度,那这种情况这个旋转轴加上旋转角度。
那自然就形成了一个轴,一个表示这个轴表示就是轴角表示,那或者再进一步的,我们其实可以把这个旋转轴,因为它旋转轴是一个向量,是一个单位向量,然后角度是一个啊一个实数,那么其实可以把他俩乘起来。
得到一个得到一个向量,这个限量其实就是所谓的rotation vector,就是这个旋转向量,其实旋转下面和旋转这个主角表示其实可以很容易互相转化的,我只要去求一个模,然后做一个正确的。
所以做一个这个单位单位单位化就会做到这件事情了,那当然我知道一个轴角表示一个u和fa,我去旋转一个向量,其实不是那么容易的,我们其实是没有办法,就是我们其实,是需要做做这个变化的话。
我们是需要把这个旋转首先转化成一个旋转矩阵,会用这个罗德里格斯啊,罗德里格公式,罗里科罗德里格旋转公式,或者是把它转化一个旋转矩阵,或者用这样一个插针点乘的方式才能去把它进行运算。
所以这个其实在运算上来说还是有一定的这个复杂度的,另外一个问题,就是说旋转向量加上旋转向量得到的那个值,并不等于这个两个旋转的组合,这也是特别注意的地方,就是就是它其实这个组合本身是不容易算的。
比如说比如说我有一个旋转a比,如说一个旋转,一个旋转b分别表示旋转向量的形式,我要想找到一个旋转向量c,然后它对应于这个a和b的旋转的组合,那我其实能做的方式也只能是说把它们分别转化成旋转矩阵。
做一个乘法,然后再转换回来,只是基本基本是唯一可行的方式,所以说对于旋转矩阵来说啊,对对旋转向量或者主角表示来说,我想做这种啊旋转组合其实比较困难的,但是另外一方面,其实旋转向量是比较容易去做差值的。
比如说我有一个旋转a,我可以把它这个第一个选项,这个这个旋转向量c,零和另外一个选项c1 ,那我们其实可以直接做一个线性差值,那这个线性插值结果首先他得到的还是一个合法的旋转向量。
因为旋转性本身我任何一个向量都可以表示一个合法的旋转,不管它是零或者是什么一个奇怪的值,但是有一个问题就是说什么呢,如果说我只是简单的做这样一个线性差值,它其实是不保不保啊。
不保证我的这个旋转速度是恒定的,那这个其实证明起来就比较复杂了,我们这里就不讲了,但是确实是有这样一个结论,但是如果说我们想要为了实现一个这,个这个固定速度的这样一个旋转。
那这个其实计算起来就比较复杂了,其实还是可以通过旋转矩阵,旋转向量来实现,当然我们需要怎么做呢,我们首先先计算一下旋转向量零和旋转向量零一之间的差,然后把这个差转化成一个旋转向量。
然后再去做这个在这个差的旋转向量和零之间做一个线性差值,然后得到了其实是一个新的新的这个旋转,那从这个新的旋转我们可以进一步的得到我们所得到的差值,这个旋转,那这个其实是可以保证它这个旋转速度是恒定的。
那这个计算就,比较复杂了,所以总的来说呢,我们其实旋转向量也是可以很容易地表达一个矩阵旋转的,因为我们也知道一个旋转其实它就是一个旋转,沿着某一个轴旋转某一个角度这样的形式。
所以旋转向量和轴角表示其实也是很自然的,但是对于这个表述来说,同样的它表示不唯一的,首先这个轴角和我轴和脚分别取负取相反,是同样一个旋转,另外就是让这个这个角度本身加上2n派,它也是对应相同的旋转。
所以实际上这个首先旋转矩阵啊,就这个旋转的主角表示或者学生向量表示它,其实是比较容易构造的,因为我随便拿三个数过来,它就是一个合法,不好意思,他是一个合法的旋转,但是相对于奥拉甲来说。
这个我这个旋转矩阵其实是不太容易去去这个去去创建的,就是虽然说我随便找三个数,就是一个合法的旋转矩阵,但是如果说我想让某一个物体旋转到我想要的一个角度上,我靠旋转向量或者主角表示是非常困难的。
然后另外就是说这个旋转向量它本身是没办法直接去旋转一个啊矩阵,一个一个向量的,我们总是需要把它转换成一个旋转矩阵才能去做,这件事情,然后另外对于旋转向量的线性差值是可以实现一个旋转的一个差值的。
那当然它并不是完美的,就是特别是首先我需要去处理这个几点问题,就是前面这个特别是说这个因为在加二派的时候,我们需要处理一下我们到底是在哪一个二派范围区间内进行插值。
另外一个问题就是说它的这个就是直接我去做一个线性差值的话,它其实并不能保证啊这个旋转的速度是恒定的这样一个性质,那最后呢其实是我们也是非常重要的一部分,就是这个cturning就是我们的四元数。
这个四元数就是实际上其实其实我们很多时候也是拿来用一用,但是我们其实还是会最好稍微了解一下,关于四元数的一些定义和基本计算,虽然说怎么来的这样一个问题。
当然四元数其实它的出发点就是来自于是对二维旋转的一个扩展,因为我们知道二维旋转我们是可以很容易地把它表示成一个负数的,就特别是比如我在把负面认为是二维坐标啊,坐标系。
那么这个负面是复平面上一个限量的啊旋转,那其实刚好是对应一个单位负数,那这如果就是因为这样的话,其实我们可以只付出了很多计算,我们可以很容易的就是可以进行进行计算,那如何把这个东西去扩展到三维。
其实这个就是非常难的一个问题了,这个不是那么直观的,就是二位是比较紧的,三维就就一下子变得难了很多,所以实际上之前有一个人,有一个科学家,一个数学家叫哈密顿,我们后面会提到,其实哈密顿还是做了很多事情。
他就花了很多时间来干这件事情,那段时间我们可以其实在我们知道答案的情况下,我们就可以简单回顾一下,那首先一个复数我们通常把它写成a加上b乘以i,还是一个负数的一个标志,一个单位。
那他基本一个性质是i的平方等于-1,那为了把它扩展,那我们其实可以很显然我们可以再加一个,再加一个量,再加一个g我们可以要求这一类的平方也等于-1,但是这和i是不相等的。
那其实我们就把这个负数稍微扩展了一点,那类似的其实我们可以进一步的扩展,比如说再定义一辆k,那这个k的平方也是-1,同时k的i和j也是不相等的那一类,我们可以定义无限的定义出去。
那当然对于这个cturning,对于四元数来说,实际上我们就就是形式上来说,差不多就是负数的这样的一个扩展,但它是i j k有三个复数的这样一个机理,然后这个辅助基地本身是满足一些性质的。
首先每个的平方等于-1,其次三个系列的乘积合成一起也是-1,但这个其实就是我们定义了,就像那个负数单位一样,为什么i的平方等于-1,没有,为什么他定义就是这样子,那当然它带来一,些很好的性质。
这是我们比较喜欢的,那另外就是说我们它是满足一些,这类似于这个坐标轴差成的这样的一个一些性质,比如i g等于k那反过来j乘以x等于负k的这样的一些关系。
当然前面提到的这个哈密顿其实是是一个非常有名的数学家,物理学家,就是这个大家可能我们这门课后面会涉及到一点这个啊拉格朗日力学,但是这个哈密顿其实是后面他还有另外一套方法,就是去去重新用哈密顿量。
它定义就是提出了一组哈密顿量来重新定义这个啊,重新把这个力学体系,给公理化,当然哈密顿量如果大家学量子力学的话,会经常用到的,因为在那边是那边一个非常常用的一个工具。
但是哈密顿花了很长时间来想这个三维的旋转该怎么表示,因为就是怎么去把一个二维的负数给扩展到三维旋转上,直到有一天他在一个桥上散步的时候,诶突然灵感爆发,然后想起了这个这样一个表示。
那最后把他就是为了纪念这件事情,他把这个这个这个东西刻成一个扁,还踢的那个小声,所以这是这个也是他自己认为这是他最大的贡献哈,那当然这个,但其实这个,前面这个定义。
前面i j k的这个定义其实就已经定义好了,我这个次元数他的各种计算的一些规则,比如说对于四元数来说,类似于负数,比如复数有共轭,那四元数其实也是有共轭的。
因为复数的共轭就是它虚部的负号取负号得到的共轭,对于四元数来说,因为有三个西部,那么实际他的工作就是三三个西部分别取符号那类似的,比如说做这个啊,现在这个这个标量的乘法或者加减法,或者是点乘。
或者是这个这个啊nb这个这个发型啊,这个这个叫什么来着,范数其实都是类似于我,们的那个复数的定义其实都是这样一个啊,其实可以就是一些线性向量的一些计算,那这里其实稍微有点麻烦一点是什么呢。
是这个四元数的乘法,因为四元数的乘法,因为每个四元数都是写成a b c d,然后乘以i j k这样的一个形式,所以说曲线我们可以用分配率,然后加上我们前面提到的对于i和j和k这几个复数啊。
标记在这样一个这个运算关系,我们是可以最终得到它的向量差,两个向量对两个四元数分别是a b c d,它乘乘积还是个算数,那这个四元数其实是比较哎,呀写的比较比较乱了,大概其实是每一项是这样的一个形式。
那他这个结界比较乱了,所以说实际上我们经常来说还是会把它这个四元数稍微剪辑一点,因为我知道虽然数是x啊,w前面是一个标量,加上x y z分别是对应i j k上的一个坐标值。
那我们实际上可以把q把这个这个算数,我们就直接写成一个一个标量w和一个w呃,这个这个xyz方向它认为是一个三三啊,三维的一个一个单位,一个向量写成这样的一个形式,那在这种情况实行之下呢。
其实我们还有一些扩展,比如说,一个标量本身它其实也是一个四元数,只不过它里边这个向量的部分是零,然后类似的一个项链,我们也可以认为它还是它也是一个四元数,只不过它的标量部分是零。
或者这东西也叫一个纯四元数,那在这样的基础定义之下,那么前面那堆东西可以重新再写一遍,就是这个比如说共轭,那我其实只有向量部分去取复,然后这个标的部分是不变的。
然后其他的其实计算其实就是非常非常简单的向量运算,然后在这种情况下,我们可以看到乘法乘法它其实前面那一堆很复杂的公式,其,实最后变成了类似于这样的一个形式,看起来比较简洁了,那这里其实可以发现。
其实这个这个向量的部分的,在成绩里边解呃的值其实是前面部分加上一个插成,所以说就是为什么插成其实为什么插成是从这儿来的,就是也是因为前面那堆奇怪的公式推一推。
最后发现其实这个对应的这部分其实刚好对于差成为形式,那当然其实他就是四元数的很多性质其实跟矩阵是相似的,就是这个q一乘q2 是不等于k2 乘q e的,但是呢它是满足,结合律的这跟前面差乘是不一样的。
这是跟矩阵的乘法是相同的,就是我q a乘q2 乘以q3 ,我们是可以可以随意去结合来进行运算,那类似的就是类似于这个转制,这是机人的转制,我们知道这个嗯溯源数的这个共轭。
比如qq乘q2 的共轭等于q1 ,q2 的共轭乘以q的q一的共轭就刚好反过来,然后类似的这个像是啊就是它的这个这个范数的平方,其实也是这个每个点就是q的啊,共轭乘以q本身。
那另外一个就可以类似于这个这个相反呃,逆袭阵我们其实也可以定义一个,一个四元数的倒数,四元数乘以它本身等于一的时候,这里两个四元数相乘等于一的时候,那这两个数互相互相等于倒数,那对于四元数来说。
q的倒数等于q的共轭除以q的长度啊,平方就是这个就是说其实这也很容易可以从前面的四元数的运算,乘法的运算规则里得到,那这些在这些定义基础之上呢,我们其实更关心的是什么呢,更关心的是所谓的单位四元数。
也就是它的模长,它的长度等于一等这样的四元数,那但对于任何任何一个非零的四元数来说,我们是可以同很容易的,把这个它它本身除以它的模长来得到一个单位四元数,单对单位四元数来说。
其实它有点类似于我们前面学的正交阵,单位四元数的逆等于它的功,或者它计算是非常简单的,就是这个把它的向量部分取一个负值,那只是单位算出一个非常好的一个性质,那其实我可以回顾一下,我们其实对于负数来说。
一个负数,它其实单位复数就是模长等于一的负数,它其实是构造啊,会分布在这个复平面上的一个圆环上,就这个这个一个一个一维的圆环,在二维平面上,那当然他可以写成一个sin。
和cos sin函数的形式把它写出来,那类似的对于一个单位四元数,一个单位四元数,因为它是一个四个啊,它具有四个四维的一个量,因为v是v是一个向量,是一个三维向量。
w本身有额外一位是他是一个四维的一项单位啊,单位单位的点,所以实际上所有的单位四元数如果把它看成点的话,每一个看成一个点的话,那它其实构成了一个四维空间上的一个单位求和。
所以这是一个单位四元数的一个一个就是跟那个一个平面,这个选这个圆环的一个类比,那类似的我们其实可以把单位,岁数写成一个类似于这样的形式,相对于cos 2分的fa,它是一个对角数啊,sorry。
这个这个这个三角函数以及一个向量部分是一个u这样的一个方式,那为什么这么写呢,我们后面大家可以看到,那回到其实我们对于任何一个单位四元数来说,我们总是可以写成这样的一个形式,其实主要还是因为什么呢。
因为w的平方加上v的长度的平方等于一,这是这是由我单位这个单位长度决定的,所以我们其实这样它的平方的和等于一的话,那我们其实可以一部分是cos,不是sin,我们,总是可以把它写成类似于这样的形式的。
那这里其实有几个量,首先是sa,另外是u,这u是一个单位阵啊,sorry是一个啊单位向量,然后fter是一个类似于角度的一个东西,所以我们可以看到它其实是跟我们的轴角表示有相同的数量的信息。
我主角表示也是一个向量代表轴,一个单位向量代表轴和一个fa代表的角度,所以实际上他俩他俩共用的真心,所以啊涉及到的信息是相同的,并且但是唯一的不同点就是优势,在不同的形式上,主角表示就是轴夹角。
那四元素其实是cos,然后这样一个,乘积的形式,那实际上这样一个对应其实也是带来一个结论,就是说我们任何一个三维的旋转,那首先我们能把它变成一个轴角表示,其次我们可以把它对应到相应的单位四元数。
就可以直接把一个轴角表示转化成对应的四元数表示,那这里就是sa,但我知道四元数时候其实可以这么c他啊就是或者反过来的,我知道这样一个四元数他写成w和v这样的形式之后,我其实可以得到它对应的轴角表示什么。
它fa是可以通过这样的方式进行计算,然后u其实对这个v做一个这个这,个这个单位换啊,其实可以得到,所以说实际上就是任何一个轴角,任何旋转,它所对应的轴角跟一个四元数是可以对应的。
当然这个对应并不是一一对应的,但是它是一个满射,那接下来呢就是说如果说在这样一个表示之下,我希望我有一个单位的单位四元数,然后它所对应一个轴角,我希望对于这个轴角表示的对应这个旋转。
把一个向量p做做一个学生之后得到了一个p撇,那么p p和p之间是什么关系,这个其实是可以直接有一个结论的,但是这个推这个推的过程我就不讲了,这个结论就是说p因为首先它是一个向量,作为一个三维向量来说。
我们可以认为它是一个纯四元素,也就是说它的这个标量部分是零,那对这个旋转本身的作用其实可以写成这样的形式,也是q是我们的这个旋转所对应的单位四元数,乘以我这个纯四纯四元数。
就是这个位置这个三维向量所对应的纯四纯四元数,然后再乘以q的这个共轭,或者等价来说,他也是q的逆,这个其实可以证明的这个乘法,四元数的乘法所得到的值对应的标量部分肯定是零,然后这个对应的这个向量。
部分它刚好是等于我做按照这个轴角进行旋转之后,得到那个限量它的值,所以说再进一步,就是说实际上我如果说我需要用一个四元素对一个向量进行旋转,那其实是只要做一个这样的一个夹心三明治的乘法。
一个类似于这样的形式,其实也回答了为什么我们前面这里是一个二倍的,是一个二分之c,实际上我们可以大概某种程度上可以认为他做一次乘法,是把这东西转了20只c的,然后因为这里做了两次惩罚。
所以实际是做了两个4/2项,所以最终是赚了一个c的大,概是这样一个这样一个这样一个理解,那当然从这个公式我们可以进一步得到,如果说我这两边各成一个符号,我们其实可以知道这个它所对应的是同样一个旋转。
这就是说对于四元数来说,它的表示也不是唯一的,就是一个四元数,一个单位四元数和这个单位四元数的负号就是相反,方向所代表的是同样的一个旋转,这是四元数的一个性质。
那同样的类似于我们这个啊三维旋转矩阵的这样一个这个组合,我们其实可以很容易通过一些简单的推导,我们可以得到对于两个四元数,两个单位四元数,每个四元数代表一个旋转。
它们所组合的那个旋转其实刚好是这两个四元数的积,所以这个其实是为什么四元数大家都比较喜欢用呢,因为首先它的数量这个参数比较少,而且我们刚才提到的,比如说轴角表示,如果我想把一个主角和另外一个主角。
它的旋转进行组合,我们是没办法非常简单的通过主角运算来实现的,类似的对于一个这个欧拉角来说,欧拉角相对比较简单一点,因莫拉角我们可以总是可以把它变成一个矩阵,因为他每一个角对应一个矩阵嘛。
但是这个主角对于奥拉脚本身的表示来说,我们是没办法,比如说把这个三个角度三相加减来实现这样一个运算的,所以只有算数在这个方面是比较有优势的,那对于四元数来说,我们同样面临一个问题。
就是说我们还是对消对旋转进行插值,比如说我有一个在零时刻,我,有一个旋转对应四元数q01 时刻有一个旋转对应,虽然q一那中间时刻我都能旋转,应该是多少,其实还是回顾一下。
其实我们还是提到了我们一个单位四元数,它最终表现出来是一个四维空间上的一个球壳,然后我们其实需要插值的两个四元数,q一和q2 或者q0 q一吧,然后它其实是这个求求和上的两个点,那我们想要做差值。
实际上我们是希望能够在求和上找到一个轨迹,然后这个轨迹对应的是我的一堆差值点,为什么要在,为什么要在球球和山找,因为我只有求可山的,点才是单位四元数,只有单位四元数才是对应于我们的一个旋转矩阵。
它它是一个对应一个旋转,它它是一个合法的旋转,所以这是我们的一个要求,那当然我们其实可以稍微把它简化一下,就是从这个理解方面,我们还是把它画成一个二维的,就比如说我是沿着就是沿着前面这个q1 q2 。
然后还有中心原点,我可以把它挂在一个平面,然后把这个平面切一下这个球,那么其实得到了一个二维的一个一个这样一个表示表示,那当然其实类似于前面的,比如说轴角表示啊,或者是比如。
说欧拉角表示我们其实也是可以直接做一个线性差值的,当然线性差值的最大的问题就是说,这个因为我们要求是只有在这个求格上,它才是一个合法的资源数,而在这个情况下,我们信差值得到这个点。
他其实是不在这个这个求这个这个这个呃求和上面,所以它不是一个合法的这个四元数,那为了能把它合法化,那我们其实知道任何一个算数,我们把它做一次这个啊单位换,那其实对应的一个单位四元数。
那这就是一个合法的四元数了,那这种情况下就是首先这种这种差值加上,线性差值加上这个映射得到的这种方式,首先大家确实是一定程度是work的,首先为什么呢,因为首先得到这个值它是一个单位四元数。
我们知道单位四元数就是一个合法的旋转,所以说至少这个插值方式它是能够实现合法的旋转的,当然缺点是什么呢,缺点是这个旋转速度并不是恒定的,因为这个可以大概看出来。
我们虽然我们在这个直线上取取了间隔相等的四个点,然后这四点分别做这个做这个production,做这个投影,可以发现它前面这段是比较密的啊,比较密的,后面一段比较基础的。
然后因为这四个点我们可以认为相同时间,所以它时间次效果就是前面会转的慢一点,然后中间会转的快一点,然后再转的慢一点,所以这实际上也是,但这也是一定程度上会有,它不是一个不是一个恒定速度的一个差值。
但是对于四元数来说,实际上这个实际在使用过程中,它的这个可能其实变化不是那么明显,为什么呢,因为主要是说我们在做四元数差值的时候,我们最远最远会差多少,实际上我们在四元数插值,我们不会差得非常远的。
就是如果说比如说正常,也比如cm差值,其实还回到刚才的问题,其实现在差距有,另外如果说我这四元数在这边,他是零,那这个时候我做这样这样一个正交化啊,这个这个单位化是不对,是没有。
而是不能做这个正单位化的,因为这个模长是零,但是对于四元数来说,其实有一个刚才也提到,它有一个特点是说对镜点是代表相同的旋转,所以实际上我做插值的时候,我其实碰到这种情况。
我完全可以把这个点就直接把找他的在这个上面的对应点,所以实际上我是做了一个非常近的一个差值,反而它其实是没有问题的,所以这四人数来说,其实如果说我们正确的判断的这个最呃最近点,我们总是去做在这两个。
就是在这两个差值点所对应的那个最近的那一半那个半径上进行差值,我们是可以保证这样一个线性差值加上这个映射这种方式,它永远是能够给出一个合法的四元数的表示,但是缺点就是说它可能是这个速度是不恒定的。
当然实际上我们还有一种想法,就是我们如果说我们想让这个速度恒定,我们该怎么办,那这种其实就是引入一个技术,叫做snp。
就是suspherical spherical linear interpolation啊,这个好像被我的这个相机挡住了,那这种情况就是说什么呢,我们其实还是一种某种程度上还是一个产线性差值。
或者不是检查,我们是一个差值,我们知道差值就是说我需要计算a和b的两个系数,用这两个系数分别乘以我前面的两个这个两两端点的这个位置,那那得到这样一个差值,那a和b应该是一个什么样的一个什么样的形式。
才能实现一个常数速度的差值呢,那当然这里其实有些推导啊,就是说实践是我们可以把这样假设它是一个旋转之后,我们可以通过把a和b分别点成两边的这个p和q,就是两边的端点的这个向量,我们可以进行求解。
那这个推导过程我们就不仔细讲了,但最终结论就是说我们可以得到这样一个形式,就是a和b分别是这样的一个三角函数的比值,和这样一个三角函数的比值,其中这个sa是两端点作为向量,它们之间的夹角。
那这样一个这样一个差值方式得到的就是把a和b作为系数,形成了这样一个差值方式,得到这个这个这个这个差值就叫那它实现的是什么呢,就是它是可以实现在插值过程中,我的这个角速度是恒定的,这是这是一个基本形式。
所以说对于这个cturning,对于这个四元数差值来说,通常我们用两种方式,就是前面首先前面的线性差值加上映射,虽然说他有时候会有这个速度问题,但是其实很多时候也也是能用的,而且好处是说什么呢。
它不需要进行sl函数计算,它的整个计算量是比较小的,另外说如果说我们对这个速度非常敏感的,那么是可以用这个slab插值,插值的方式就是稍微复杂一点,我们是先计算一下两个向量之间的这个夹角。
那其实这个对应的在每一个插值点上,它所对应的这个差值系数其实是这样的一个形式,ok那我们最后总结一下我们这个旋转矩啊,cturning,那我们知道其实query是一个对一个负数的一个扩展。
那当然它满足一些复数的一扩展出来的一些一些运算的规则,那么首先我们知道对于任何一个旋转,任何一个三维旋转,我们都可以把它表示成一个单位的四元数,那这个单位四元数我们可以对应主角的方式。
就是刚好是写可以写成一个cos arm thea和u乘以sin,二分之thea这样的一个形式,那当然虽然只有一个特性,就是说它的表示也不是唯一的,就是q一个四元数和它的这个负数是表示的是一个相同的旋转。
大家好,这是说什么呢,就是说对于一个四元数来说,我们其实可以通过四元数的乘法,比较容易的对一个三维的向量进行旋转操作,当然这个对于虽然说来说,虽然说它有四个量,所有四呃,四个变量。
但是我们去构造它也是相同的,是比较容易的,我们其实可以随便找四个数,然后把它做一次单位化,那其实就得到了一个单位四元素,那它其实就对应了一个旋转,那当然类似于主角其实是同样的问题。
就是如果说我们想要实现某一个特定的旋转,就是就是它其实每个变量的值跟它有具体的某一个旋转,其实是没有直观的映射的,现在这个里边其实只有欧拉角才有这么一个相对来说比较直观的映射,另外就是跟主角不一样。
这个四元数用四元数来去旋转一个啊向量,那相对是比较容易的,可以很容易实现另外四元素的这个在四元数表示基础之上进行插值,我们可以slap来来实现一个这个长速度的这个这样一个差值,那当然这里还有一个问题。
就是我们还是需要去处理一些这个界面点问题,就是这个起点问题主要来自于什么呢,是来自于这个q和副q代表相同的旋转,所以说我每次插值的时候,我们其实是需要做一些,比如q一和q2 做成差值。
我们通常是需要把其中的一个判断一下,他跟q一的夹角是不是是不是大于100,大于90度哎,大运玩动算应该大于90度,然后如果不是的话,我们举一个相反数来把它变到同一个半球里面,那这样的话我们可以插值。
可以至少可以这个计算起来,其实更加通常来讲是我们想要的方向,而这个slop实际上也是说它代表的是一个什么产值,代表是说从一个旋转a到一个旋转b之间最短的这样的一个差值过程。
所以这也是一个stop或者四元数。
能够提供给我们的一个非常好的一个性质,ok那其实我们这节课也是讲了很久了,我发现这个直接讲了,发现比我预期的还要久一些,那总的来说我们今天主要内容就是回顾一下我们的这个在这个方向。
我在角色动画里边我们会用到的一些线性代数的知识,特别是这个旋转的一些表示,然,后另外我们这后面也提到了很多关于关于四元数的这个旋转轴角,虽然数和欧拉角还有个旋转矩阵的各自的性质。
还有特别是我们在插值的时候需要注意的一些问题,那当然这个下节课呢我们就是还是在记在这个,今天这节课呢就是呃内容之上呢,我们会进一步的往后面去介绍,首先是比如说我们怎么去在这个基于坐标转换。
来实现一个项运动学的计算,然后另外其实有两个非常重要的内容,其实也是可以给大家做一个思考题啊,就是说其实在那个旋转啊,在这个角色动画里,面其实有一个非常重要的问题,就是重定向,首先象征题是什么呢。
就是说我一个角色它的初始姿态是teapos或者a pos,这两个之间的动作,我们是不能直接把它旋转给拷贝过去的,那这个过程中我们是需要做一点运算,才能让这个这个程序它是正确的,那这东西怎么做。
那我们下节课会做进一步的介绍,那除此之外,现在我们也会涉及到关于这个逆向动力学的内容,好那我们今天的这个主要的讲课的部分就就就就到这里,然后看大家有什么问题,当然今天来说还是比较简单的部分了。
因为都是学过的一些先行代数的内容,哇这个东西比较多,首先这四个旋转方法在哪,哪个在科研用的比较多,其实怎么说呢,我觉得哪个方向哪个都有用的,就是说其实最近也是各种讨论到底是哪一种方法。
哪一种哪一种表示会更好,就是说其实我就是一些实验啊,有些人是觉得可能用这个啊旋转矩阵或者更加具体来说,其实是旋转矩阵的前两个,前两列其实是六个六个变量,就是所谓的6d vector来表示一个旋转。
可能这个好像更好一些,但是我个人觉得其实可能这个区别比较不是那么大,就说你其实理论上你用任何一个表示都是都是有可能的,当然比如说你要用这个四元数,其实你要面临一个问题,做一个这个单位化,但实际反过来。
即使你用stud vector他得到,另外说你是希望这因为你是输出的是这个啊矩阵矩阵的前两个轴啊,前两个列你是希望这两列首先它是一个正交呃,首先他们这两列是互相正交了,其实他们是单位向量。
那这个过程中实际你还是要做做做这个对角化,其实我觉得可能从效果来说,这个不是最关键的部分,说实话他只是说你可能主要算法完成了之后,你再去挑一条哪个更好,那可能就只是实验上觉得哪个好一些。
考虑到缩放的transform,其实这个其实我们今天主要还是其实还是稍微提了一下,就是说我们一般做这个transformation,比如说在软件里面常用的一些方式,都是说可能是先做缩放,再做旋转。
然后再做这个平移,大概这样一个性质,但实际上我们任何一个其实本质上如果是加了缩放之后呢,这个这个transformation这个变换其实是就不再是一个正交变换了,而是一个随便一个矩阵的这样一个变换。
但我们其实可以总是可以把它分解出来,分解成一系列的旋转,加上缩放,加上平移这样的一个组成形式,所以说实际上这个呃用什么样的表,就是就是就是这个这个过程其实是可以很容易实现的。
就什么样的组合其实都是可以都可以都是可以实现的,然后欧拉角的12种顺序找一找,ok这里其实就是说比如说第一种诶,不好意思。
比如说第一种顺序x y z取决于我是用哪一种,哪一种convention,就是哪一种方式,比如说我说是固定固定旋转轴的,就是跟世界固定的旋转轴的这样一个x y z,它是代表什么呢。
它是代表我是先沿着z轴旋转,再沿着y轴旋转,再沿着x轴旋转,都是在世界这样一个范围内,那类似的,比如说x z x他表示我首先沿着世界的x轴旋转一下,然后再沿着世界的z轴旋转一下。
然后最后还是沿着世界的x轴又旋转了一下,那得到了这样一个顺序,那如果说我们是表示一个浮动的,就是这种就是,在这个物体空间的这样一个旋转轴的话,那其实x x x都是也其实同样的也是先进的x轴转。
转z也是z轴,转z也是x轴转,只不过每次旋转的时候,对应的那个旋转他是在用的是这个局部的一个坐标轴,当然局部坐标轴我们其实是实践在计算的时候,我们还是需要把它转化成全局的坐标轴才能去计算呢。
那这怎么转换,其实只要把轴转换过去之后,我们其实可以用轴角表示转化成旋转矩阵这种方式来去计算这个旋转,所以这是这个这个这个欧拉角这个顺序的问题,但实际上,我们常用的一般就是x y z和z y x。
然后可能有些时候会见到y z x这样的一个选项,但是这个其他的可能都不是那么常用,啊为什么正确判断最近点可以线性插值映射,这个应该说的是四元数啊,我们前面其实也提到了。
就说四元数,找一张就算。
是。
对这个就是刚才我们提到了,就是说如果说是一个线性差值,比如说我这个点虽然数分别在这个直径的两边,就是因为每个球馆上每一个点都是一个合理的旋转,所以说他有可能是说q0 是在这边,q一是在这边。
那我们直接做一个线性差值的话,你会发现在中间这个点的时候,它的这个差值的这个资源数变成了零,然后它这个首先这个零本身不是一个合法的旋转,我们需要把它变成这个映射到这个单位球上,才能是一个合法旋转。
但是零这零长度的一个四元数,我们是没有办法把它映射出去的,因为它的模长是零,所以说这个除法是做不了的,所以为了能够做到这一点,因为还是考虑到四元数在次元四这个这个次元求和上的一个特点。
就是首先四元数它和它的相反数是同样一个四元数,所以说当我这个点出现在这边的时候,比如咱俩这个他俩的这个差实际上超过了多少呢,其实可以想象一下,如果它超过了二分之派,实际上就是这两个的距离超过了二分之派。
我们总是可以比如在这个点,比如说q0 q一在这里,然后我q2 q0 在这里,然后他们俩之间的夹角超过了二分之派,那我们其实可以把q0 直接取它的相反数,直接相反数在这边了,那这边的时候。
它其实跟这个克零是在同样一个二分之派的一个范围内的,那这个时候我们是可以直接去做这样的一个做这样一个差值,那做这样一个线性差值,它就不会过零点了,而实际上我们在这里举这个例子也是同样的。
其实你会发现q0 和q一它们的夹角其实是大于20派,所以实际上我是可以把q0 我不做,不做这个q0 ,q一的差值,我可以把q一找它的相反数找到这边来。
然后这个点和这个q0 这两个之间的夹角是小于小于二分之派,所以实际上来说对于我们这个差值加映射啊,加加这个投影这样的方式,你会发现我这线性线性差值的时候,我是从来不会差值超过二分之派的这样一个角度的。
所以这是可以保证,我这个差值总是可以去被映射到这个这个单位球上的,所以它这个差值总是一个合法的一个差值,哎呀还有万象锁,万象锁这个我我其实刚才已经解释了一下,我不知道那个你你就是你那边还是什么问题啊。
但万象所这个问题在于,我觉得对于我们常用的这个常见的情况来说,它最大的问题就是在万向锁的时候,他的表示是不唯一的,这个其实是比较严重的问题,就是在这个时候你会发现,因为这两个轴是平行的嘛。
所以这两个轴比如说外面的轴可以增加10度,里面那个轴轴减少10度,那它对应的这个旋转是一个相同的旋转,所以这种情况下其实它表示是不唯一的,那其实表示不唯一,其实也是对应的,他其实肯定是一个没有解的点。
就是就是我把这个这个旋转转化成这个三个旋转的表示的时候,这个解可能是也是不唯一的,那这个时候你可能会遇到一些数值上的问题,所以这可能是外向解锁,对我们这个这个比较比较难比较难受的一个情况。
那当然还是那个问题,就是虽然说他确实在这个时间上,他不可能靠这个结构本身产生一个另外一个自由度的旋转,但是我在外界依然可以加一个就是在这个结构之外的旋转,来打破这个完全解锁,所以这个其实是没有问题的。
他只是在这个瞬间,我靠结构,比如这是一个机械臂,或者就是这么一个就是这么一个这个这个陀螺仪,我在这个瞬间,其实图里本身它的物理,它的这个结构已经就不允许我在某一个方向上进行旋转。
致使这个万劫所带来的问题,ok转两圈以上怎么表示,就转两圈,其实你转一圈跟跟没转是相同的,所以转两圈以上,本质上来说你可以减掉,减掉若干个二派,那最后得到的其实是相同的旋转,但这里其实有一个问题。
就是说我们其实后面提到的几种几种这个啊旋转表示,比如说像是轴角表示,主角表示其实有一个特点,就是说它是呃theta是可以任意取值的,诶,哪里去了,不好意思,对现在可以任意取值的,就是我也来说。
比如说我转两圈,我觉得可以从零开始始终往上涨,不断的往上涨,然后我都说我在做插值的时候,可以只是就是就在这个连续的这样一个theta的范围内进行差值,那其实可以保证我这个人一直在那一直在那旋转。
这个是没有问题的,对于query来说,其实也是一样的,但是我们需要额外处理一下,就是我们始终保持差值的时候,他都是在相同的1/4半球,这样的话我们可以让那个差值出来的结果还是一个正确的。
但如果说你要是从这个等价性来,说那确实是说我转两圈和转一圈没有本质区别,它它它其实是同样的一个旋转,就是这样一个问题,多个四元数差值有什么办法,这个其实我们这里没有讲了。
但是这个其实有些工作是做这件事情的,就是比较老的一些工作,我们可以回头这个我们可以提一些啊相关的论文,就是实际上比如说对于线性的点,我们比如说可以我后面会讲到这个关于差值的问题。
就是这个就是关键帧怎么做差值,就比如说我们线性插值是一种方式,我们可以比如说四个点,我们可以做一些splg,做一些这种样条插值,那对于这个嗯四元数来说,其实也有对应的这样流差值的方法,但是会非常复杂。
但是它,也是可以查的,ok行我觉得这个时间也差不多了,那个我们其他的问题可以,大家可以在我们这个微信群,然后我们会有助教,然后我自己也只会尽量给大家进行解答,那我们今天的课程就到这里了。
那时间也是有点超时,也是非常感谢大家一直这个听到最后,那我们这个下周啊同一时间再继续啊。