Skip to content

Commit aa61eb5

Browse files
authored
Merge pull request #3209 from saihv/PR/voxel_grid
Voxel grid construction
2 parents 7664c42 + c823d6d commit aa61eb5

File tree

10 files changed

+115
-11
lines changed

10 files changed

+115
-11
lines changed

AirLib/include/api/RpcLibClientBase.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class RpcLibClientBase {
107107
void simSetCameraFov(const std::string& camera_name, float fov_degrees, const std::string& vehicle_name = "");
108108
// This is a backwards-compatibility wrapper over simSetCameraPose, and can be removed in future major releases
109109
void simSetCameraOrientation(const std::string& camera_name, const Quaternionr& orientation, const std::string& vehicle_name = "");
110-
110+
bool simCreateVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file);
111111
msr::airlib::Kinematics::State simGetGroundTruthKinematics(const std::string& vehicle_name = "") const;
112112
msr::airlib::Environment::State simGetGroundTruthEnvironment(const std::string& vehicle_name = "") const;
113113

AirLib/include/api/WorldSimApiBase.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class WorldSimApiBase {
6767
virtual std::unique_ptr<std::vector<std::string>> swapTextures(const std::string& tag, int tex_id = 0, int component_id = 0, int material_id = 0) = 0;
6868
virtual vector<MeshPositionVertexBuffersResponse> getMeshPositionVertexBuffers() const = 0;
6969

70+
virtual bool createVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file) = 0;
71+
7072
// Recording APIs
7173
virtual void startRecording() = 0;
7274
virtual void stopRecording() = 0;

AirLib/src/api/RpcLibClientBase.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@ msr::airlib::Environment::State RpcLibClientBase::simGetGroundTruthEnvironment(c
406406
{
407407
return pimpl_->client.call("simGetGroundTruthEnvironment", vehicle_name).as<RpcLibAdapatorsBase::EnvironmentState>().to();;
408408
}
409+
bool RpcLibClientBase::simCreateVoxelGrid(const msr::airlib::Vector3r& position, const int& x, const int& y, const int& z, const float& res, const std::string& output_file)
410+
{
411+
return pimpl_->client.call("simCreateVoxelGrid", RpcLibAdapatorsBase::Vector3r(position), x, y, z, res, output_file).as<bool>();
412+
}
413+
409414

410415
void RpcLibClientBase::cancelLastTask(const std::string& vehicle_name)
411416
{

AirLib/src/api/RpcLibServerBase.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ RpcLibServerBase::RpcLibServerBase(ApiProvider* api_provider, const std::string&
344344
const Environment::State& result = (*getVehicleSimApi(vehicle_name)->getGroundTruthEnvironment()).getState();
345345
return RpcLibAdapatorsBase::EnvironmentState(result);
346346
});
347+
pimpl_->server.bind("simCreateVoxelGrid", [&](const RpcLibAdapatorsBase::Vector3r& position, const int& x, const int& y, const int& z, const float& res, const std::string& output_file) -> bool {
348+
return getWorldSimApi()->createVoxelGrid(position.to(), x, y, z, res, output_file);
349+
});
347350

348351
pimpl_->server.bind("cancelLastTask", [&](const std::string& vehicle_name) -> void {
349352
getVehicleApi(vehicle_name)->cancelLastTask();

PythonClient/airsim/client.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,19 @@ def simSetWind(self, wind):
790790
"""
791791
self.client.call('simSetWind', wind)
792792

793+
def simCreateVoxelGrid(self, position, x, y, z, res, of):
794+
"""
795+
Construct and save a binvox-formatted voxel grid of environment
796+
797+
Args:
798+
position (Vector3r): Position around which voxel grid is centered in m
799+
x, y, z (float): Size of each voxel grid dimension in m
800+
res (float): Resolution of voxel grid in m
801+
of (str): Name of output file to save voxel grid as
802+
803+
"""
804+
return self.client.call('simCreateVoxelGrid', position, x, y, z, res, of)
805+
793806
# ----------------------------------- Multirotor APIs ---------------------------------------------
794807
class MultirotorClient(VehicleClient, object):
795808
def __init__(self, ip = "", port = 41451, timeout_value = 3600):
@@ -1255,4 +1268,4 @@ def getCarControls(self, vehicle_name=''):
12551268
CarControls:
12561269
"""
12571270
controls_raw = self.client.call('getCarControls', vehicle_name)
1258-
return CarControls.from_msgpack(controls_raw)
1271+
return CarControls.from_msgpack(controls_raw)

Unity/AirLibWrapper/AirsimWrapper/Source/WorldSimApi.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ void WorldSimApi::setWeatherParameter(WeatherParameter param, float val)
103103
//TODO: implement weather for Unity
104104
}
105105

106+
bool WorldSimApi::createVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file)
107+
{
108+
return false;
109+
}
110+
106111
//----------------Plotting APIs-----------/
107112
void WorldSimApi::simFlushPersistentMarkers()
108113
{

Unity/AirLibWrapper/AirsimWrapper/Source/WorldSimApi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase
6262
virtual bool isRecording() const override;
6363

6464
virtual void setWind(const Vector3r& wind) const override;
65+
virtual bool createVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file) override;
6566

6667
private:
6768
SimModeBase * simmode_;

Unreal/Environments/Blocks/Blocks.uproject

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
"Enabled": true
2020
},
2121
{
22-
"Name": "SteamVR",
23-
"Enabled": false
24-
},
25-
{
26-
"Name": "OculusVR",
27-
"Enabled": false
28-
},
22+
"Name": "SteamVR",
23+
"Enabled": false
24+
},
25+
{
26+
"Name": "OculusVR",
27+
"Enabled": false
28+
}
2929
]
30-
}
30+
}

Unreal/Plugins/AirSim/Source/WorldSimApi.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,79 @@ AActor* WorldSimApi::createNewActor(const FActorSpawnParameters& spawn_params, c
161161
return NewActor;
162162
}
163163

164+
bool WorldSimApi::createVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file)
165+
{
166+
bool success = false;
167+
int ncells_x = x_size / res;
168+
int ncells_y = y_size / res;
169+
int ncells_z = z_size / res;
170+
171+
voxel_grid_.resize(ncells_x * ncells_y * ncells_z);
172+
173+
float scale_cm = res * 100;
174+
FCollisionQueryParams params;
175+
params.bFindInitialOverlaps = true;
176+
params.bTraceComplex = false;
177+
params.TraceTag = "";
178+
auto position_in_UE_frame = simmode_->getGlobalNedTransform().fromGlobalNed(position);
179+
for (float i = 0; i < ncells_x; i++) {
180+
for (float k = 0; k < ncells_z; k++) {
181+
for (float j = 0; j < ncells_y; j++) {
182+
int idx = i + ncells_x * (k + ncells_z * j);
183+
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;
184+
voxel_grid_[idx] = simmode_->GetWorld()->OverlapBlockingTestByChannel(position, FQuat::Identity, ECollisionChannel::ECC_Pawn, FCollisionShape::MakeBox(FVector(scale_cm /2)), params);
185+
}
186+
}
187+
}
188+
189+
std::ofstream output(output_file, std::ios::out | std::ios::binary);
190+
if (!output.good())
191+
{
192+
UE_LOG(LogTemp, Error, TEXT("Could not open output file to write voxel grid!"));
193+
return success;
194+
}
195+
196+
// Write the binvox file using run-length encoding
197+
// where each pair of bytes is of the format (run value, run length)
198+
output << "#binvox 1\n";
199+
output << "dim " << ncells_x << " " << ncells_z << " " << ncells_y << "\n";
200+
output << "translate " << -x_size * 0.5 << " " << -y_size * 0.5 << " " << -z_size * 0.5 << "\n";
201+
output << "scale " << 1.0f/x_size << "\n";
202+
output << "data\n";
203+
bool run_value = voxel_grid_[0];
204+
unsigned int run_length = 0;
205+
for (size_t i = 0; i < voxel_grid_.size(); ++i)
206+
{
207+
if (voxel_grid_[i] == run_value)
208+
{
209+
// This is a run (repeated bit value)
210+
run_length++;
211+
if (run_length == 255)
212+
{
213+
output << static_cast<char>(run_value);
214+
output << static_cast<char>(run_length);
215+
run_length = 0;
216+
}
217+
}
218+
else
219+
{
220+
// End of a run
221+
output << static_cast<char>(run_value);
222+
output << static_cast<char>(run_length);
223+
run_value = voxel_grid_[i];
224+
run_length = 1;
225+
}
226+
}
227+
if (run_length > 0)
228+
{
229+
output << static_cast<char>(run_value);
230+
output << static_cast<char>(run_length);
231+
}
232+
output.close();
233+
success = true;
234+
return success;
235+
}
236+
164237
bool WorldSimApi::isPaused() const
165238
{
166239
return simmode_->isPaused();

Unreal/Plugins/AirSim/Source/WorldSimApi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase {
6565
virtual bool isRecording() const override;
6666

6767
virtual void setWind(const Vector3r& wind) const override;
68+
virtual bool createVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file) override;
6869

6970
private:
7071
AActor* createNewActor(const FActorSpawnParameters& spawn_params, const FTransform& actor_transform, const Vector3r& scale, UStaticMesh* static_mesh);
@@ -73,4 +74,5 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase {
7374
private:
7475
ASimModeBase* simmode_;
7576
ULevelStreamingDynamic* current_level_;
76-
};
77+
std::vector<bool> voxel_grid_;
78+
};

0 commit comments

Comments
 (0)