我正在写一个基本的游戏引擎来帮助我的关于多智能体学习的PhD主题。我使用PyBullet作为后端物理引擎,使用OpenGL进行可视化显示。我设置了OpenGL缓冲区来保存对象信息,如位置(Vec3)和旋转(Matrix4x4),旋转是使用四元数完成的,但为了方便起见,使用了Euler角度进行存储。
我的问题是,当我在OpenGL游戏世界中旋转一个对象(绕任何轴)时,pyBullet旋转(从pyBullet图形用户界面中看到)是在相反的方向上,有时完全关闭。我肯定遗漏了一些基本的东西,如果这是一个简单的修复,我很抱歉。我还提供了一段视频来显示我遇到的问题-链接到错误视频(https://youtu.be/4VpBUx5LBYQ):
当我使用getBasePositionAndOrientation()从PyBullet提取旋转,并使用pybullet.getEulerFromQuaternion()将四元数转换为欧拉角时,结果是正确的vec3,但在转换为旋转矩阵pybullet.getMatrixFromQuaternion()时,它似乎颠倒了旋转方向。
下面是我的代码:
'obj = Class BaseSceneObject'
'action = Euler rotation angle in degrees to apply vec3(x, y, z) e.g.(1., 0., 0.) apply +1 degree rotation to x-axis'
'Collect current position and rotation of object and update PyBullet'
# get the rotation - euler angles in degrees vec3(x,y,z)
rot = obj.get_rotation()
# add rotation action (e.g. +1 degree to x = vec3(1., 0., 0.)) and convert to radians
rot = math.radians(rot[0] + action[0]), math.radians(rot[1] + action[1]), math.radians(rot[2] + action[2])
# convert rotation from euler to quaternion
quat = pybullet.getQuaternionFromEuler(rot)
# update position and orientation
pybullet.resetBasePositionAndOrientation(bodyUniqueId=obj.get_rigid_body_id(),
posObj=obj.get_position(),
ornObj=quat)
'Collect PyBullet results and update OpenGL'
# get position and rotation from PyBullet
position, rotation = pybullet.getBasePositionAndOrientation(bodyUniqueId=obj.get_rigid_body_id())
# update object position
obj.set_position(position=position)
# convert rotation quaternion to euler angles
rot_r = pybullet.getEulerFromQuaternion(rotation)
# convert radians to degrees
rot_d = math.degrees(rot_r[0]), math.degrees(rot_r[1]), math.degrees(rot_r[2])
# construct OpenGL object rotation matrix
rot_m_final = numpy.identity(4)
rot_mr = numpy.array(pybullet.getMatrixFromQuaternion(rotation)).reshape(3, 3)
rot_m_final[:3, :3] = rot_mr
# update OpenGL rotation matrix
obj.set_rotation(rotation=rot_d,
rotation_matrix=rot_m_final)发布于 2020-08-10 05:51:54
事实证明上面的代码是正确的。问题存在于OpennGL着色器中,其中我忘记了矩阵计算是非可交换的,即numpy.matmul(Mat4(旋转),Vec4(位置))与numpy.matmul(Vec4(位置),Mat4(旋转))不同。
将着色器代码从: vec4 aRPos = vec4(aRotation * aVertex);更新为: vec4 aRPos = vec4(aVertex * aRotation);
它工作得很完美。谢谢。
https://stackoverflow.com/questions/63327951
复制相似问题