Pybullet中矩阵变换相关API介绍

前言

  最近看Pybullet官方手册,发现关于几个矩阵变换的函数解释的不够详尽,虽然心里明白他的用途,但用起来没那么放心,故在此总结一番

invertTransform

  官方手册只提到输入参数以及输出参数,看不到底层源码,我就自己写了个测试代码,可以确定该函数求取的是齐次变换矩阵的逆矩阵:
[ R v 0 1 ] − 1 = [ R − 1 − R − 1 v 0 1 ] (1) \left[ \begin{matrix} R & v \\ 0 & 1 \end{matrix} \right]^{-1}= \left[ \begin{matrix} R^{-1} & -R^{-1}v \\ 0 & 1 \end{matrix} \right]\tag{1} [R0v1]1=[R10R1v1](1)
在这里插入图片描述
  其中position表示齐次变换的 v v v,而旋转矩阵 R R R是由第二个参数中的四元数转换而来的,转换规则自行查阅资料,这里只用知道四元数 q = [ x , y , z , w ] q=[x,y,z,w] q=[x,y,z,w]转换为轴角表达如下:
  设旋转轴为 r = [ i , j , k ] r=[i,j,k] r=[i,j,k],旋转角度为 θ \theta θ,则表示绕轴 r r r旋转 θ \theta θ角的四元数 q q q为: [ x = i ⋅ s i n ( θ 2 ) , y = j ⋅ s i n ( θ 2 ) , z = k ⋅ s i n ( θ 2 ) , w = c o s ( θ 2 ) ] [x=i \cdot sin(\frac{\theta}{2}),y=j \cdot sin(\frac{\theta}{2}),z=k \cdot sin(\frac{\theta}{2}),w=cos(\frac{\theta}{2})] [x=isin(2θ),y=jsin(2θ),z=ksin(2θ),w=cos(2θ)],测试代码如下:

import pybullet as p
import numpy as np

# v:求逆前齐次变换的位置变换v
# q:求逆前表示旋转变换的四元数
v= [2, 1, 0]
q= [0, 0.5 ** 0.5, 0, 0.5 ** 0.5]  # 绕y轴旋转90度
# v_:求逆后齐次变换的位置变换v_
# q_:求逆前表示旋转变换的四元数
v_, q_ = p.invertTransform(v, q)  # 求逆
print(v_)  # (0.0, -1.0, -2.0)

R = p.getMatrixFromQuaternion(q)  # 获取求逆前的旋转矩阵
R_ = p.getMatrixFromQuaternion(q_)  # 获取求逆后的旋转矩阵

np_R = np.array([list(R[0: 3]), list(R[3: 6]), list(R[6: 9])],dtype=float)
np_R_ = np.array([list(R_[0: 3]), list(R_[3: 6]), list(R_[6: 9])],dtype=float)
inv_R = np.linalg.inv(np_R)  # 求逆前的旋转矩阵手动求逆

print(inv_R)  # 与np_R_比较相同
print(-(inv_R @ v))  # 与v_比较相同
print(np_R_)

multiplyTransforms

  经过实际测试发现这其实就是由两个(四元数-位置变换组)组成的齐次变换矩阵的矩阵乘法,具体哪个齐次矩阵乘在左侧,也不清楚,测试如下:
在这里插入图片描述  从下面代码测试发现应该由positionA-orientationA组成的齐次矩阵左乘positionB-orientationB组成的齐次矩阵,亦即先进行A齐次变换,再到A变换的基础上进行B齐次变换:

import pybullet as p
import numpy as np

def Transform(v, q):
    R = p.getMatrixFromQuaternion(q)  # 获取旋转矩阵
    # 拼凑齐次矩阵
    slices = [list(R[0: 3]), list(R[3: 6]), list(R[6: 9])]
    for i in range(3):
        slices[i].append(v[i])
    np_R = np.array(slices)
    bottom = np.array([0, 0, 0, 1])
    T = np.vstack((np_R, bottom))  # 在底部补齐
    # print(T)
    return T


v1 = [3, 2, 1]
q1 = [0, 0.5 ** 0.5, 0, 0.5 ** 0.5]  # 绕y轴旋转90度

v2 = [1, 2, 3]
q2 = [0, 0, 0.5 ** 0.5, 0.5 ** 0.5]  # 绕z轴旋转90度

v, q = p.multiplyTransforms(v1, q1, v2, q2)
T1 = Transform(v1, q1)
T2 = Transform(v2, q2)

T_test1 = T1 @ T2
T_test2 = T2 @ T1
print(f"T1在左侧结果:{T_test1}")
print(f"T2在左侧结果:{T_test2}")

T_after = Transform(v, q)
print(f"multiplyTransforms函数求取的结果:{T_after}")
#T_fter和T_test1结果相同

  本文到这就结束了,因为其他相关的API官网解释的很清楚了,大家看官网资料吧,有问题留在评论区,大家一起探讨呀,或者还有其他需要我进一步探索的,欢迎留言

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值