AirSim bietet eine Funktion, die Ground-Truth-Voxelgrids der Welt direkt aus der Unreal Engine erstellt. Ein Voxelgrid ist eine Darstellung der Belegung einer gegebenen Welt/Karte, indem diese in Zellen einer bestimmten Größe diskretisiert wird; und ein Voxel aufgezeichnet wird, wenn sich an dieser bestimmten Stelle etwas befindet.
Die Logik zum Erstellen des Voxelgrids befindet sich in WorldSimApi.cpp -> createVoxelGrid(). Vorerst wird davon ausgegangen, dass das Voxelgrid ein Würfel ist - und der API-Aufruf von Python hat die Struktur
simCreateVoxelGrid(self, position, x, y, z, res, of)
position (Vector3r): Global position around which voxel grid is centered in m
x, y, z (float): Size of each voxel grid dimension in m
res (float): Resolution of voxel grid in m
of (str): Name of output file to save voxel grid as
Innerhalb von createVoxelGrid() ist die Hauptfunktion der Unreal Engine, die die Belegung zurückgibt, OverlapBlockingTestByChannel.
OverlapBlockingTestByChannel(position, rotation, ECollisionChannel, FCollisionShape, params);
Diese Funktion wird an den Positionen aller 'Zellen' aufgerufen, in die wir die Karte diskretisieren möchten, und das zurückgegebene Belegungsergebnis wird in einem Array voxel_grid_ gesammelt. Die Indizierung der Zellbelegungswerte folgt der Konvention des binvox-Formats.
for (float i = 0; i < ncells_x; i++) {
for (float k = 0; k < ncells_z; k++) {
for (float j = 0; j < ncells_y; j++) {
int idx = i + ncells_x * (k + ncells_z * j);
FVector position = FVector((i - ncells_x /2) * scale_cm, (j - ncells_y /2) * scale_cm, (k - ncells_z /2) * scale_cm) + position_in_UE_frame;
voxel_grid_[idx] = simmode_->GetWorld()->OverlapBlockingTestByChannel(position, FQuat::Identity, ECollisionChannel::ECC_Pawn, FCollisionShape::MakeBox(FVector(scale_cm /2)), params);
}
}
}
Die Belegung der Karte wird iterativ über alle diskretisierten Zellen berechnet, was zu einer intensiven Operation werden kann, abhängig von der Auflösung der Zellen und der Gesamtgröße des zu messenden Bereichs. Wenn sich die Karte des Benutzers nicht stark ändert, ist es möglich, die Voxelgrid-Operation einmal auf dieser Karte auszuführen und das Voxelgrid zu speichern und wiederzuverwenden. Für Leistung oder in dynamischen Umgebungen empfehlen wir, die Voxelgrid-Generierung für einen kleinen Bereich um den Roboter herum auszuführen; und sie anschließend für lokale Planungszwecke zu verwenden.
Die Voxelgrids werden im binvox-Format gespeichert, das der Benutzer dann in ein Octomap .bt oder ein anderes relevantes, gewünschtes Format konvertieren kann. Anschließend können diese Voxelgrids/Octomaps für Mapping/Planung verwendet werden. Ein nettes kleines Dienstprogramm zur Visualisierung von erstellten binvox-Dateien ist viewvox. Ebenso kann binvox2bt die binvox-Datei in eine Octomap-Datei konvertieren.
Beispiel-Voxelgrid in Blocks:#

Blocks Voxelgrid konvertiert in Octomap-Format (visualisiert in rviz):#

Als Beispiel kann ein Voxelgrid wie folgt erstellt werden, sobald die Blocks-Umgebung gestartet und läuft
import airsim
c = airsim.VehicleClient()
center = airsim.Vector3r(0, 0, 0)
output_path = os.path.join(os.getcwd(), "map.binvox")
c.simCreateVoxelGrid(center, 100, 100, 100, 0.5, output_path)
Und visualisiert durch viewvox map.binvox.