如何在AIRSIM中访问网格#

AirSim支持访问构成场景的静态网格。

网格结构#

每个网格都用以下结构表示。

struct MeshPositionVertexBuffersResponse {

    Vector3r position;
    Quaternionr orientation;

    std::vector<float> vertices;
    std::vector<uint32_t> indices;
    std::string name;
};

  • 位置和方向在虚幻坐标系中。
  • 网格本身是一个由顶点和索引表示的三角网格。
    • 三角网格类型通常称为面-顶点网格。这意味着每三个索引构成一个三角形/面。
    • 顶点的x、y、z坐标都存储在一个向量中。这意味着顶点向量是Nx3,其中N是顶点数量。
    • 顶点的位置是虚幻坐标系中的全局位置。这意味着它们已经经过位置和方向的变换。

如何使用#

获取场景中网格的API非常简单。但是,需要注意的是,该函数调用非常耗时,应极少调用。通常情况下这没有问题,因为此函数只访问静态网格,而对于大多数应用程序而言,这些网格在程序运行期间不会发生变化。

请注意,您需要使用第三方库或您自己的自定义代码才能实际与接收到的网格进行交互。下面我将利用libigl的Python绑定来可视化接收到的网格。

import airsim

AIRSIM_HOST_IP='127.0.0.1'

client = airsim.VehicleClient(ip=AIRSIM_HOST_IP)
client.confirmConnection()

# List of returned meshes are received via this function
meshes=client.simGetMeshPositionVertexBuffers()


index=0
for m in meshes:
    # Finds one of the cube meshes in the Blocks environment
    if 'cube' in m.name:

        # Code from here on relies on libigl. Libigl uses pybind11 to wrap C++ code. So here the built pyigl.so
        # library is in the same directory as this example code.
        # This is here as code for your own mesh library should require something similar
        from pyigl import *
        from iglhelpers import *

        # Convert the lists to numpy arrays
        vertex_list=np.array(m.vertices,dtype=np.float32)
        indices=np.array(m.indices,dtype=np.uint32)

        num_vertices=int(len(vertex_list)/3)
        num_indices=len(indices)

        # Libigl requires the shape to be Nx3 where N is number of vertices or indices
        # It also requires the actual type to be double(float64) for vertices and int64 for the triangles/indices
        vertices_reshaped=vertex_list.reshape((num_vertices,3))
        indices_reshaped=indices.reshape((int(num_indices/3),3))
        vertices_reshaped=vertices_reshaped.astype(np.float64)
        indices_reshaped=indices_reshaped.astype(np.int64)

        # Libigl function to convert to internal Eigen format
        v_eig=p2e(vertices_reshaped)
        i_eig=p2e(indices_reshaped)

        # View the mesh
        viewer = igl.glfw.Viewer()
        viewer.data().set_mesh(v_eig,i_eig)
        viewer.launch()
        break