730 lines
21 KiB
C++
730 lines
21 KiB
C++
/*
|
|
* Copyright (C) 2012 Open Source Robotics Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <ignition/math/Vector3.hh>
|
|
|
|
#include "gazebo/common/SystemPaths.hh"
|
|
#include "gazebo/rendering/RenderingIface.hh"
|
|
#include "gazebo/rendering/Scene.hh"
|
|
#include "heights_cmp.h"
|
|
#include "gazebo/test/helper_physics_generator.hh"
|
|
#include "images_cmp.h"
|
|
#include "gazebo/test/ServerFixture.hh"
|
|
|
|
using namespace gazebo;
|
|
|
|
std::mutex mutex;
|
|
unsigned char* img = NULL;
|
|
|
|
/////////////////////////////////////////////////
|
|
void OnNewCameraFrame(int* _imageCounter, unsigned char* _imageDest,
|
|
const unsigned char *_image,
|
|
unsigned int _width, unsigned int _height,
|
|
unsigned int _depth,
|
|
const std::string &/*_format*/)
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
memcpy(_imageDest, _image, _width * _height * _depth);
|
|
*_imageCounter += 1;
|
|
}
|
|
|
|
class HeightmapTest : public ServerFixture,
|
|
public testing::WithParamInterface<const char*>
|
|
{
|
|
public: void PhysicsLoad(const std::string &_physicsEngine);
|
|
public: void WhiteAlpha(const std::string &_physicsEngine);
|
|
public: void WhiteNoAlpha(const std::string &_physicsEngine);
|
|
public: void Volume(const std::string &_physicsEngine);
|
|
public: void LoadDEM(const std::string &_physicsEngine);
|
|
public: void Material(const std::string &_worldName,
|
|
const std::string &_physicsEngine);
|
|
|
|
/// \brief Test loading a heightmap that has no visuals
|
|
public: void NoVisual();
|
|
|
|
/// \brief Test loading a heightmap with an LOD visual plugin
|
|
public: void LODVisualPlugin();
|
|
|
|
/// \brief Test loading a heightmap and verify cache files are created
|
|
public: void HeightmapCache();
|
|
|
|
public: void NotSquareImage();
|
|
public: void InvalidSizeImage();
|
|
// public: void Heights(const std::string &_physicsEngine);
|
|
};
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::PhysicsLoad(const std::string &_physicsEngine)
|
|
{
|
|
if (_physicsEngine == "dart")
|
|
{
|
|
gzerr << "Aborting test for dart, see issue #909" << std::endl;
|
|
return;
|
|
}
|
|
|
|
Load("worlds/heightmap_test.world", true, _physicsEngine);
|
|
|
|
// Make sure the render engine is available.
|
|
if (rendering::RenderEngine::Instance()->GetRenderPathType() ==
|
|
rendering::RenderEngine::NONE)
|
|
{
|
|
gzerr << "No rendering engine, unable to run heights test\n";
|
|
return;
|
|
}
|
|
|
|
physics::ModelPtr model = GetModel("heightmap");
|
|
EXPECT_TRUE(model != NULL);
|
|
|
|
physics::CollisionPtr collision =
|
|
model->GetLink("link")->GetCollision("collision");
|
|
|
|
physics::HeightmapShapePtr shape =
|
|
boost::dynamic_pointer_cast<physics::HeightmapShape>(
|
|
collision->GetShape());
|
|
|
|
EXPECT_TRUE(shape != NULL);
|
|
EXPECT_TRUE(shape->HasType(physics::Base::HEIGHTMAP_SHAPE));
|
|
|
|
EXPECT_TRUE(shape->GetPos() == ignition::math::Vector3d(0, 0, 0));
|
|
EXPECT_TRUE(shape->GetSize() == ignition::math::Vector3d(129, 129, 10));
|
|
|
|
common::Image trueImage("media/materials/textures/heightmap_bowl.png");
|
|
common::Image testImage = shape->GetImage();
|
|
|
|
common::SystemPaths *paths = common::SystemPaths::Instance();
|
|
testImage.SavePNG(paths->GetTmpPath() + "/test_shape.png");
|
|
|
|
EXPECT_EQ(trueImage.GetWidth(), testImage.GetWidth());
|
|
EXPECT_EQ(trueImage.GetHeight(), testImage.GetHeight());
|
|
|
|
// Debug output
|
|
// Compare the true image to the image generated by the heightmap shape
|
|
// for (uint16_t y = 0; y < testImage.GetHeight(); y += 1.0)
|
|
// {
|
|
// for (uint16_t x = 0; x < testImage.GetWidth(); x += 1.0)
|
|
// {
|
|
// // EXPECT_NEAR(trueImage.GetPixel(x, y).r,
|
|
// // testImage.GetPixel(x, y).r, 0.008);
|
|
// // if (fabs(trueImage.GetPixel(x, y).r - testImage.GetPixel(x, y).r)
|
|
// // > 0.008)
|
|
// {
|
|
// printf("XY[%d %d] True[%f] Test[%f]\n", x, y,
|
|
// trueImage.GetPixel(x, y).r, testImage.GetPixel(x, y).r);
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::WhiteAlpha(const std::string &_physicsEngine)
|
|
{
|
|
if (_physicsEngine == "dart")
|
|
{
|
|
gzerr << "Aborting test for dart, see issue #909" << std::endl;
|
|
return;
|
|
}
|
|
|
|
Load("worlds/white_alpha_heightmap.world", true, _physicsEngine);
|
|
physics::ModelPtr model = GetModel("heightmap");
|
|
EXPECT_TRUE(model != NULL);
|
|
|
|
physics::CollisionPtr collision =
|
|
model->GetLink("link")->GetCollision("collision");
|
|
|
|
physics::HeightmapShapePtr shape =
|
|
boost::dynamic_pointer_cast<physics::HeightmapShape>(collision->GetShape());
|
|
|
|
EXPECT_TRUE(shape != NULL);
|
|
EXPECT_TRUE(shape->HasType(physics::Base::HEIGHTMAP_SHAPE));
|
|
|
|
int x, y;
|
|
for (y = 0; y < shape->GetVertexCount().y; ++y)
|
|
{
|
|
for (x = 0; x < shape->GetVertexCount().x; ++x)
|
|
{
|
|
EXPECT_NEAR(shape->GetHeight(x, y), 10.0, 1e-4);
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::WhiteNoAlpha(const std::string &_physicsEngine)
|
|
{
|
|
if (_physicsEngine == "dart")
|
|
{
|
|
gzerr << "Aborting test for dart, see issue #909" << std::endl;
|
|
return;
|
|
}
|
|
|
|
Load("worlds/white_no_alpha_heightmap.world", true, _physicsEngine);
|
|
physics::ModelPtr model = GetModel("heightmap");
|
|
EXPECT_TRUE(model != NULL);
|
|
|
|
physics::CollisionPtr collision =
|
|
model->GetLink("link")->GetCollision("collision");
|
|
|
|
physics::HeightmapShapePtr shape =
|
|
boost::dynamic_pointer_cast<physics::HeightmapShape>(collision->GetShape());
|
|
|
|
EXPECT_TRUE(shape != NULL);
|
|
EXPECT_TRUE(shape->HasType(physics::Base::HEIGHTMAP_SHAPE));
|
|
|
|
int x, y;
|
|
for (y = 0; y < shape->GetVertexCount().y; ++y)
|
|
{
|
|
for (x = 0; x < shape->GetVertexCount().x; ++x)
|
|
{
|
|
EXPECT_EQ(shape->GetHeight(x, y), 10.0);
|
|
}
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::NotSquareImage()
|
|
{
|
|
common::SystemPaths::Instance()->AddGazeboPaths(
|
|
TEST_INTEGRATION_PATH);
|
|
|
|
this->server = new Server();
|
|
this->server->PreLoad();
|
|
// EXPECT_THROW(this->server->LoadFile("worlds/not_square_heightmap.world"),
|
|
// common::Exception);
|
|
|
|
this->server->Fini();
|
|
delete this->server;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::InvalidSizeImage()
|
|
{
|
|
common::SystemPaths::Instance()->AddGazeboPaths(
|
|
TEST_INTEGRATION_PATH);
|
|
|
|
this->server = new Server();
|
|
this->server->PreLoad();
|
|
// EXPECT_THROW(this->server->LoadFile("worlds/invalid_size_heightmap.world"),
|
|
// common::Exception);
|
|
|
|
this->server->Fini();
|
|
delete this->server;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::Volume(const std::string &_physicsEngine)
|
|
{
|
|
if (_physicsEngine == "simbody")
|
|
{
|
|
// SimbodyHeightmapShape unimplemented. ComputeVolume actually returns 0 as
|
|
// an error code, which is the correct answer, but we'll skip it for now.
|
|
gzerr << "Aborting test for "
|
|
<< _physicsEngine
|
|
<< std::endl;
|
|
return;
|
|
}
|
|
if (_physicsEngine == "dart")
|
|
{
|
|
gzerr << "Aborting test for "
|
|
<< _physicsEngine
|
|
<< ", see issue #909" << std::endl;
|
|
return;
|
|
}
|
|
|
|
Load("worlds/heightmap_test.world", true, _physicsEngine);
|
|
|
|
physics::ModelPtr model = GetModel("heightmap");
|
|
EXPECT_TRUE(model != NULL);
|
|
|
|
physics::CollisionPtr collision =
|
|
model->GetLink("link")->GetCollision("collision");
|
|
|
|
physics::HeightmapShapePtr shape =
|
|
boost::dynamic_pointer_cast<physics::HeightmapShape>(
|
|
collision->GetShape());
|
|
|
|
EXPECT_DOUBLE_EQ(shape->ComputeVolume(), 0);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::LoadDEM(const std::string &_physicsEngine)
|
|
{
|
|
#ifdef HAVE_GDAL
|
|
if (_physicsEngine == "dart")
|
|
{
|
|
gzerr << "Aborting test for dart, see issue #909" << std::endl;
|
|
return;
|
|
}
|
|
|
|
if (_physicsEngine == "bullet" || _physicsEngine == "simbody")
|
|
{
|
|
gzerr << "Aborting test for " << _physicsEngine <<
|
|
", negative elevations are not working yet." << std::endl;
|
|
return;
|
|
}
|
|
|
|
Load("worlds/dem_neg.world", true, _physicsEngine);
|
|
|
|
physics::WorldPtr world = physics::get_world("default");
|
|
ASSERT_NE(world, nullptr);
|
|
|
|
physics::ModelPtr boxModel = GetModel("box");
|
|
ASSERT_NE(boxModel, nullptr);
|
|
|
|
ignition::math::Pose3d boxInitPose(0, 0, -207, 0, 0, 0);
|
|
EXPECT_EQ(boxModel->GetWorldPose().Ign(), boxInitPose);
|
|
|
|
physics::ModelPtr model = GetModel("heightmap");
|
|
ASSERT_NE(model, nullptr);
|
|
|
|
physics::CollisionPtr collision =
|
|
model->GetLink("link")->GetCollision("collision");
|
|
|
|
physics::HeightmapShapePtr shape =
|
|
boost::dynamic_pointer_cast<physics::HeightmapShape>(
|
|
collision->GetShape());
|
|
|
|
ASSERT_NE(shape, nullptr);
|
|
EXPECT_TRUE(shape->HasType(physics::Base::HEIGHTMAP_SHAPE));
|
|
|
|
EXPECT_TRUE(shape->GetPos() == ignition::math::Vector3d(0, 0, 0));
|
|
|
|
double maxHeight = shape->GetMaxHeight();
|
|
double minHeight = shape->GetMinHeight();
|
|
EXPECT_GE(maxHeight, minHeight);
|
|
EXPECT_GE(boxInitPose.Pos().Z(), minHeight);
|
|
|
|
// step the world
|
|
// let the box fall onto the heightmap and wait for it to rest
|
|
world->Step(1000);
|
|
|
|
ignition::math::Pose3d boxRestPose = boxModel->GetWorldPose().Ign();
|
|
EXPECT_NE(boxRestPose, boxInitPose);
|
|
EXPECT_GE(boxInitPose.Pos().Z(), minHeight);
|
|
|
|
// step the world and verify the box is at rest
|
|
world->Step(100);
|
|
|
|
ignition::math::Pose3d boxNewRestPose = boxModel->GetWorldPose().Ign();
|
|
EXPECT_EQ(boxNewRestPose, boxRestPose);
|
|
#else
|
|
// prevent unused variable warning
|
|
(void)(_physicsEngine);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
void HeightmapTest::Heights(const std::string &_physicsEngine)
|
|
{
|
|
Load("worlds/heightmap_test.world", _physicsEngine);
|
|
|
|
// Make sure the render engine is available.
|
|
if (rendering::RenderEngine::Instance()->GetRenderPathType() ==
|
|
rendering::RenderEngine::NONE)
|
|
{
|
|
gzerr << "No rendering engine, unable to run heights test\n";
|
|
return;
|
|
}
|
|
|
|
// Make sure we can get a valid pointer to the scene.
|
|
rendering::ScenePtr scene = GetScene();
|
|
ASSERT_TRUE(scene);
|
|
|
|
rendering::Heightmap *heightmap = NULL;
|
|
|
|
// Wait for the heightmap to get loaded by the scene.
|
|
{
|
|
int i = 0;
|
|
while (i < 20 && (heightmap = scene->GetHeightmap()) == NULL)
|
|
{
|
|
common::Time::MSleep(100);
|
|
i++;
|
|
}
|
|
|
|
if (i >= 20)
|
|
gzthrow("Unable to get heightmap");
|
|
}
|
|
|
|
physics::ModelPtr model = GetModel("heightmap");
|
|
EXPECT_TRUE(model);
|
|
|
|
physics::CollisionPtr collision =
|
|
model->GetLink("link")->GetCollision("collision");
|
|
|
|
physics::HeightmapShapePtr shape =
|
|
boost::dynamic_pointer_cast<physics::HeightmapShape>(collision->GetShape());
|
|
|
|
EXPECT_TRUE(shape);
|
|
EXPECT_TRUE(shape->HasType(physics::Base::HEIGHTMAP_SHAPE));
|
|
|
|
EXPECT_TRUE(shape->GetPos() == ignition::math::Vector3d(0, 0, 0));
|
|
EXPECT_TRUE(shape->GetSize() == ignition::math::Vector3d(129, 129, 10));
|
|
|
|
std::vector<float> physicsTest;
|
|
std::vector<float> renderTest;
|
|
|
|
float x, y;
|
|
|
|
for (y = 0; y < shape->GetSize().y && y < .3; y += 0.2)
|
|
{
|
|
for (x = 0; x < shape->GetSize().x && x < 1; x += 0.2)
|
|
{
|
|
// Compute the proper physics test point.
|
|
int xi = rint(x);
|
|
if (xi >= shape->GetSize().x)
|
|
xi = shape->GetSize().x - 1.0;
|
|
|
|
int yi = rint(y);
|
|
if (yi >= shape->GetSize().y)
|
|
yi = shape->GetSize().y - 1.0;
|
|
|
|
// Compute the proper render test point.
|
|
double xd = xi - (shape->GetSize().x) * 0.5;
|
|
double yd = (shape->GetSize().y) * 0.5 - yi;
|
|
|
|
// The shape->GetHeight function requires a point relative to the
|
|
// bottom left of the heightmap image
|
|
physicsTest.push_back(shape->GetHeight(xi, yi));
|
|
|
|
// The render test requires a point relative to the center of the
|
|
// heightmap.
|
|
renderTest.push_back(heightmap->GetHeight(xd, yd));
|
|
|
|
// Debug output
|
|
if (fabs(physicsTest.back() - renderTest.back()) >= 0.04)
|
|
{
|
|
std::cout << "Render XY[" << xd << " " << yd << "] Physics XY[" << xi
|
|
<< " " << yi << "] R[" << renderTest.back() << "] P["
|
|
<< physicsTest.back() << "] D["
|
|
<< fabs(renderTest.back() - physicsTest.back()) << "]\n";
|
|
}
|
|
|
|
// Test to see if the physics height is equal to the render engine
|
|
// height.
|
|
EXPECT_NEAR(physicsTest.back(), renderTest.back(), 0.04);
|
|
}
|
|
}
|
|
|
|
float diffMax, diffSum, diffAvg;
|
|
FloatCompare(&physicsTest[0], &renderTest[0], physicsTest.size(),
|
|
diffMax, diffSum, diffAvg);
|
|
|
|
EXPECT_LT(diffMax, 0.04);
|
|
EXPECT_LT(diffSum, 0.2);
|
|
EXPECT_LT(diffAvg, 0.02);
|
|
|
|
printf("Max[%f] Sum[%f] Avg[%f]\n", diffMax, diffSum, diffAvg);
|
|
|
|
// This will print the heights
|
|
// printf("static float __heights[] = {");
|
|
// unsigned int i=0;
|
|
// for (y = 0; y < shape->GetVertexCount().y; ++y)
|
|
// {
|
|
// for (x = 0; x < shape->GetVertexCount().x; ++x)
|
|
// {
|
|
// if (y == shape->GetVertexCount().y && x == shape->GetVertexCount().x)
|
|
// break;
|
|
|
|
// if (i % 7 == 0)
|
|
// printf("\n");
|
|
// else
|
|
// printf(" ");
|
|
// printf("%f,", shape->GetHeight(x, y));
|
|
// i++;
|
|
// }
|
|
// }
|
|
// printf(" %f};\nstatic float *heights = __heights;\n",
|
|
// shape->GetHeight(x,y));
|
|
}
|
|
*/
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::Material(const std::string &_worldName,
|
|
const std::string &_physicsEngine)
|
|
{
|
|
if (_physicsEngine == "dart")
|
|
{
|
|
gzerr << "Aborting test for dart, see issue #909" << std::endl;
|
|
return;
|
|
}
|
|
|
|
// load a heightmap with red material
|
|
Load(_worldName, false, _physicsEngine);
|
|
physics::ModelPtr heightmap = GetModel("heightmap");
|
|
ASSERT_NE(heightmap, nullptr);
|
|
|
|
// spawn camera sensor to capture an image of heightmap
|
|
std::string modelName = "camera_model";
|
|
std::string cameraName = "camera_sensor";
|
|
unsigned int width = 320;
|
|
unsigned int height = 240;
|
|
double updateRate = 10;
|
|
ignition::math::Pose3d testPose(
|
|
ignition::math::Vector3d(0, 0, 100),
|
|
ignition::math::Quaterniond(0, 1.57, 0));
|
|
SpawnCamera(modelName, cameraName, testPose.Pos(),
|
|
testPose.Rot().Euler(), width, height, updateRate);
|
|
sensors::SensorPtr sensor = sensors::get_sensor(cameraName);
|
|
sensors::CameraSensorPtr camSensor =
|
|
std::dynamic_pointer_cast<sensors::CameraSensor>(sensor);
|
|
int imageCount = 0;
|
|
img = new unsigned char[width*height*3];
|
|
event::ConnectionPtr c =
|
|
camSensor->Camera()->ConnectNewImageFrame(
|
|
std::bind(&::OnNewCameraFrame, &imageCount, img,
|
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
|
|
std::placeholders::_4, std::placeholders::_5));
|
|
|
|
// grab some images
|
|
int sleep = 0;
|
|
int maxSleep = 500;
|
|
int total_images = 10;
|
|
while (imageCount < total_images && sleep++ < maxSleep )
|
|
common::Time::MSleep(10);
|
|
EXPECT_GE(imageCount, total_images);
|
|
|
|
camSensor->Camera()->DisconnectNewImageFrame(c);
|
|
|
|
unsigned int rSum = 0;
|
|
unsigned int gSum = 0;
|
|
unsigned int bSum = 0;
|
|
for (unsigned int i = 0; i < height*width*3; i+=3)
|
|
{
|
|
unsigned int r = img[i];
|
|
unsigned int g = img[i+1];
|
|
unsigned int b = img[i+2];
|
|
rSum += r;
|
|
gSum += g;
|
|
bSum += b;
|
|
}
|
|
|
|
// verify that red is the dominant color in the image
|
|
EXPECT_GT(rSum, gSum);
|
|
EXPECT_GT(rSum, bSum);
|
|
|
|
delete [] img;
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::NoVisual()
|
|
{
|
|
// load a heightmap with no visual
|
|
Load("worlds/heightmap_no_visual.world", false);
|
|
physics::ModelPtr heightmap = GetModel("heightmap");
|
|
ASSERT_NE(heightmap, nullptr);
|
|
|
|
gazebo::rendering::ScenePtr scene = gazebo::rendering::get_scene("default");
|
|
ASSERT_NE(scene, nullptr);
|
|
|
|
// make sure scene is initialized and running
|
|
int sleep = 0;
|
|
int maxSleep = 30;
|
|
while (scene->SimTime().Double() < 2.0 && sleep++ < maxSleep)
|
|
common::Time::MSleep(100);
|
|
|
|
// no heightmaps should exist in the scene
|
|
EXPECT_EQ(scene->GetHeightmap(), nullptr);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::LODVisualPlugin()
|
|
{
|
|
// load a heightmap with no visual
|
|
Load("worlds/heightmap_lod_plugin.world", false);
|
|
physics::ModelPtr heightmap = GetModel("heightmap");
|
|
ASSERT_NE(heightmap, nullptr);
|
|
|
|
gazebo::rendering::ScenePtr scene = gazebo::rendering::get_scene("default");
|
|
ASSERT_NE(scene, nullptr);
|
|
|
|
// make sure scene is initialized and running
|
|
int sleep = 0;
|
|
int maxSleep = 30;
|
|
while (scene->SimTime().Double() < 2.0 && sleep++ < maxSleep)
|
|
common::Time::MSleep(100);
|
|
|
|
// check the heightmap lod via scene
|
|
EXPECT_EQ(scene->HeightmapLOD(), 5u);
|
|
// check skirt length param via scene
|
|
EXPECT_EQ(scene->HeightmapSkirtLength(), 0.5);
|
|
|
|
// get heightmap object and check lod params
|
|
rendering::Heightmap *h = scene->GetHeightmap();
|
|
EXPECT_NE(h, nullptr);
|
|
EXPECT_EQ(h->LOD(), 5u);
|
|
EXPECT_EQ(h->SkirtLength(), 0.5);
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
void HeightmapTest::HeightmapCache()
|
|
{
|
|
// path to heightmap cache files
|
|
std::string heightmapName = "heightmap_bowl";
|
|
std::string heightmapDir(common::SystemPaths::Instance()->GetLogPath()
|
|
+ "/paging");
|
|
std::string shaPath = heightmapDir + "/" + heightmapName + "/gzterrain.SHA1";
|
|
std::string cachePath = heightmapDir +
|
|
"/" + heightmapName + "/gazebo_terrain_00000000.dat";
|
|
|
|
// temporary backup files for testing if cache files exist.
|
|
std::string shaPathBk = shaPath + ".bk";
|
|
std::string cachePathBk = cachePath + ".bk";
|
|
if (common::exists(shaPath))
|
|
common::moveFile(shaPath, shaPathBk);
|
|
if (common::exists(cachePath))
|
|
common::moveFile(cachePath, cachePathBk);
|
|
|
|
// there should be no cache files
|
|
EXPECT_FALSE(common::exists(shaPath));
|
|
EXPECT_FALSE(common::exists(cachePath));
|
|
|
|
// load a heightmap
|
|
Load("worlds/heightmap_test.world", false);
|
|
physics::ModelPtr heightmap = this->GetModel("heightmap");
|
|
ASSERT_NE(heightmap, nullptr);
|
|
|
|
gazebo::rendering::ScenePtr scene = gazebo::rendering::get_scene("default");
|
|
ASSERT_NE(scene, nullptr);
|
|
|
|
// make sure scene is initialized and running
|
|
int sleep = 0;
|
|
int maxSleep = 30;
|
|
while (scene->SimTime().Double() < 2.0 && sleep++ < maxSleep)
|
|
common::Time::MSleep(100);
|
|
|
|
// make sure we have the heightmap object
|
|
rendering::Heightmap *h = scene->GetHeightmap();
|
|
EXPECT_NE(h, nullptr);
|
|
|
|
// verify new sha-1 file exists
|
|
EXPECT_TRUE(common::exists(shaPath));
|
|
EXPECT_TRUE(common::isFile(shaPath));
|
|
|
|
// wait for the terrain tile cache to be saved
|
|
sleep = 0;
|
|
while (!common::exists(cachePath) && sleep++ < maxSleep)
|
|
common::Time::MSleep(100);
|
|
|
|
// verify that terrain tile cache exists
|
|
EXPECT_TRUE(common::exists(cachePath));
|
|
EXPECT_TRUE(common::isFile(cachePath));
|
|
|
|
// clean up by moving old files back
|
|
if (common::exists(shaPathBk))
|
|
common::moveFile(shaPathBk, shaPath);
|
|
if (common::exists(cachePathBk))
|
|
common::moveFile(cachePathBk, cachePath);
|
|
EXPECT_FALSE(common::exists(shaPathBk));
|
|
EXPECT_FALSE(common::exists(cachePathBk));
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_F(HeightmapTest, NotSquareImage)
|
|
{
|
|
NotSquareImage();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_F(HeightmapTest, InvalidSizeImage)
|
|
{
|
|
InvalidSizeImage();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_P(HeightmapTest, PhysicsLoad)
|
|
{
|
|
PhysicsLoad(GetParam());
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_P(HeightmapTest, WhiteAlpha)
|
|
{
|
|
WhiteAlpha(GetParam());
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_P(HeightmapTest, WhiteNoAlpha)
|
|
{
|
|
WhiteNoAlpha(GetParam());
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_P(HeightmapTest, Volume)
|
|
{
|
|
Volume(GetParam());
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_P(HeightmapTest, LoadDEM)
|
|
{
|
|
LoadDEM(GetParam());
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
//
|
|
// Disabled: segfaults ocassionally
|
|
// See https://bitbucket.org/osrf/gazebo/issue/521 for details
|
|
|
|
/*
|
|
TEST_P(HeightmapTest, Heights)
|
|
{
|
|
Heights(GetParam());
|
|
}
|
|
*/
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_P(HeightmapTest, Material)
|
|
{
|
|
Material("worlds/heightmap_material.world", GetParam());
|
|
}
|
|
|
|
// This test fails on OSX
|
|
// It uses glsl 130 which is not supported yet
|
|
#ifndef __APPLE__
|
|
/////////////////////////////////////////////////
|
|
TEST_P(HeightmapTest, MaterialShader)
|
|
{
|
|
Material("worlds/heightmap_material_shader.world", GetParam());
|
|
}
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_F(HeightmapTest, NoVisual)
|
|
{
|
|
NoVisual();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_F(HeightmapTest, LODVisualPlugin)
|
|
{
|
|
LODVisualPlugin();
|
|
}
|
|
|
|
/////////////////////////////////////////////////
|
|
TEST_F(HeightmapTest, HeightmapCache)
|
|
{
|
|
HeightmapCache();
|
|
}
|
|
|
|
INSTANTIATE_TEST_CASE_P(PhysicsEngines, HeightmapTest, PHYSICS_ENGINE_VALUES);
|
|
|
|
/////////////////////////////////////////////////
|
|
int main(int argc, char **argv)
|
|
{
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|