调用getCameraImage()获取的depthImg全为nan,请求排查问题
首先,你的depthImg全为NaN有几个明显的问题,我帮你一一拆解:
1. 透视投影的nearVal设为0是致命错误
PyBullet的computeProjectionMatrixFOV中,nearVal绝对不能设置为0!透视投影矩阵的计算依赖这个值作为分母,0会直接导致深度计算出现无穷大或NaN。这是最可能引发你问题的核心原因。
修复方式:把nearVal改成一个极小的正数,比如0.01:
projMat = p.computeProjectionMatrixFOV( fov=70.25, aspect=1.0, nearVal=0.01, # 替换原来的0 farVal=3.1)
2. camera_upvec函数存在除以0的风险
当相机位置pos_vec的z分量接近1(比如[0,0,1]),theta = arccos(pos_vec[-1])会等于0,此时sintheta = sin(theta)为0,执行phi = arccos(pos_vec[0]/sintheta)就会触发除以0的错误,生成NaN的up向量,进而导致视图矩阵完全异常。
另外,你当前的up向量计算逻辑也不够稳妥,PyBullet要求up向量必须与相机朝向(eye到target的向量)垂直,否则视图矩阵会扭曲甚至失效。
简化且安全的up向量计算方式:
不用手动计算theta和phi,直接通过向量叉乘生成正确的垂直up向量:
import numpy as np def camera_upvec(pos_vec): pos_vec = np.array(pos_vec) # 相机朝向:从eye指向target(原点) camera_dir = -pos_vec / np.linalg.norm(pos_vec) # 世界坐标系上方向 world_up = np.array([0, 0, 1]) # 计算右向量 right = np.cross(world_up, camera_dir) # 避免相机朝向与world_up平行的极端情况 if np.linalg.norm(right) < 1e-6: right = np.array([1, 0, 0]) # 最终up向量:与相机朝向和右向量都垂直 up = np.cross(camera_dir, right) return up.tolist()
或者更快速验证:针对你当前的相机位置[0.15,0.15,0.15],直接用世界上方向[0,0,1]作为up向量也完全可行,先试试这个方案快速排查问题:
up_vec = [0, 0, 1]
3. 额外检查:场景中是否有物体?
如果你的PyBullet场景是空的(没有加载任何URDF或物体),相机捕捉不到任何实体,depthImg自然会全为NaN。确保你已经通过p.loadURDF()或其他方式加载了场景物体。
测试建议
修改完上述参数后,先打印viewMat和projMat,确认没有NaN值;然后再运行getCameraImage,查看depthImg是否恢复正常。
内容的提问来源于stack exchange,提问作者Manav Kulshrestha

