我正在编写一个基本的游戏引擎,以帮助我完成关于多智能体学习的博士主题。我使用PyBullet作为后端物理引擎,并使用OpenGL进行可视化显示。我设置了OpenGL缓冲区来保存对象信息,如位置(vec3(和旋转(matrixx4x4(,使用四元数进行旋转,但为了方便起见,使用欧拉角度进行存储。
我的问题是,当我在OpenGL游戏世界中旋转一个对象(围绕任何轴(时,pyBullet的旋转(从pyBullet GUI中看到(方向相反,有时会完全关闭。我一定错过了一些基本的东西,如果这是一个简单的修复,我很抱歉。我还提供了一个视频来显示我遇到的问题-错误视频链接(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)
事实证明,上面的代码是正确的。这个问题存在于OpennGL着色器中,我忘记了矩阵计算是非通用的,即numpy.matmul(Mat4(旋转(,Vec4(位置((与numpy.matmul(Vec4(立场(,Mat4(转动((不同。
从以下位置更新着色器代码后:vec4-aRPos=vec4(aRotation*aVertex(;收件人:vec4-aRPos=vec4(a顶点*a旋转(;
它运行得很好。非常感谢。