Zugriff auf Meshes in AIRSIM#

AirSim unterstützt den Zugriff auf die statischen Meshes, aus denen die Szene besteht.

Mesh-Struktur#

Jedes Mesh wird mit der folgenden Struktur dargestellt.

struct MeshPositionVertexBuffersResponse {

    Vector3r position;
    Quaternionr orientation;

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

  • Die Position und Orientierung befinden sich im Unreal-Koordinatensystem.
  • Das Mesh selbst ist ein Dreiecks-Mesh, das durch die Vertices und die Indizes dargestellt wird.
    • Der Dreiecks-Mesh-Typ wird typischerweise als Face-Vertex Mesh bezeichnet. Das bedeutet, jedes Triplet von Indizes enthält die Indizes der Vertices, aus denen das Dreieck/die Fläche besteht.
    • Die x,y,z-Koordinaten der Vertices sind alle in einem einzigen Vektor gespeichert. Das bedeutet, der Vertices-Vektor ist Nx3, wobei N die Anzahl der Vertices ist.
    • Die Positionen der Vertices sind die globalen Positionen im Unreal-Koordinatensystem. Das bedeutet, sie wurden bereits durch die Position und Orientierung transformiert.

Verwendung#

Die API zum Abrufen der Meshes in der Szene ist recht einfach. Man sollte jedoch beachten, dass der Funktionsaufruf sehr teuer ist und sehr selten aufgerufen werden sollte. Im Allgemeinen ist dies in Ordnung, da diese Funktion nur auf die statischen Meshes zugreift, die für die meisten Anwendungen während der Laufzeit Ihres Programms nicht geändert werden.

Beachten Sie, dass Sie eine Drittanbieterbibliothek oder Ihren eigenen benutzerdefinierten Code verwenden müssen, um tatsächlich mit den empfangenen Meshes zu interagieren. Nachfolgend verwende ich die Python-Bindungen von libigl, um die empfangenen Meshes zu visualisieren.

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