diff --git a/gazebo/physics/PhysicsEngine_TEST.cc b/gazebo/physics/PhysicsEngine_TEST.cc index 1928185f87..9417c01d4f 100644 --- a/gazebo/physics/PhysicsEngine_TEST.cc +++ b/gazebo/physics/PhysicsEngine_TEST.cc @@ -125,7 +125,7 @@ void PhysicsEngineTest::PhysicsEngineParam(const std::string &_physicsEngine) { boost::any value; double maxStepSize = 0.02; - double realTimeUpdateRate = 0.03; + double realTimeUpdateRate = 3.03; double realTimeFactor = 0.04; ignition::math::Vector3d gravity(0, 0, 0); ignition::math::Vector3d magField(0.1, 0.1, 0.1); diff --git a/gazebo/rendering/Camera.cc b/gazebo/rendering/Camera.cc index 4ab9ffca46..46d1ad590d 100644 --- a/gazebo/rendering/Camera.cc +++ b/gazebo/rendering/Camera.cc @@ -909,9 +909,9 @@ unsigned int Camera::ImageDepth() const else if ((imgFmt == "BAYER_RGGB8") || (imgFmt == "BAYER_BGGR8") || (imgFmt == "BAYER_GBRG8") || (imgFmt == "BAYER_GRBG8")) return 1; - else if (imgFmt == "FLOAT32") + else if (imgFmt == "FLOAT32" || imgFmt == "R_FLOAT32") return 4; - else if (imgFmt == "FLOAT16") + else if (imgFmt == "FLOAT16" || imgFmt == "R_FLOAT16") return 2; else { @@ -980,9 +980,9 @@ int Camera::OgrePixelFormat(const std::string &_format) result = static_cast(Ogre::PF_BYTE_RGB); else if (_format == "B8G8R8" || _format == "BGR_INT8") result = static_cast(Ogre::PF_BYTE_BGR); - else if (_format == "FLOAT32") + else if (_format == "FLOAT32" || _format == "R_FLOAT32") result = static_cast(Ogre::PF_FLOAT32_R); - else if (_format == "FLOAT16") + else if (_format == "FLOAT16" || _format == "R_FLOAT16") result = static_cast(Ogre::PF_FLOAT16_R); else if (_format == "R16G16B16" || _format == "RGB_INT16" || _format == "RGB_UINT16") diff --git a/gazebo/rendering/Camera.hh b/gazebo/rendering/Camera.hh index 0cec3931e8..0ba8d1097a 100644 --- a/gazebo/rendering/Camera.hh +++ b/gazebo/rendering/Camera.hh @@ -849,6 +849,11 @@ namespace gazebo /// \return Integer representation of the Ogre image format private: static int OgrePixelFormat(const std::string &_format); + /// \brief Allow WideAngleCamera::Load to call OgrePixelFormat. + /// To avoid needing to include WideAngleCamera.hh, just befriend + /// the entire class. + friend class WideAngleCamera; + /// \brief Receive command message. /// \param[in] _msg Camera Command message. private: void OnCmdMsg(ConstCameraCmdPtr &_msg); diff --git a/gazebo/rendering/Camera_TEST.cc b/gazebo/rendering/Camera_TEST.cc index ade3844a05..d1372727bb 100644 --- a/gazebo/rendering/Camera_TEST.cc +++ b/gazebo/rendering/Camera_TEST.cc @@ -191,7 +191,7 @@ TEST_F(Camera_TEST, Create) unsigned int width = 500; unsigned int height = 300; - std::string format = "FLOAT16"; + std::string format = "R_FLOAT16"; double hfov = 1.05; double near = 0.001; double far = 200.0; @@ -239,7 +239,7 @@ TEST_F(Camera_TEST, Create) unsigned int width = 500; unsigned int height = 300; - std::string format = "FLOAT32"; + std::string format = "R_FLOAT32"; double hfov = 1.05; double near = 0.001; double far = 200.0; diff --git a/gazebo/rendering/WideAngleCamera.cc b/gazebo/rendering/WideAngleCamera.cc index ffd517d799..ebab594303 100644 --- a/gazebo/rendering/WideAngleCamera.cc +++ b/gazebo/rendering/WideAngleCamera.cc @@ -457,6 +457,10 @@ void WideAngleCamera::Load() { Camera::Load(); + // Cube map texture format defaults to matching image pixel format + this->dataPtr->envCubeMapTextureFormat = + static_cast(this->imageFormat); + this->CreateEnvCameras(); if (this->sdf->HasElement("lens")) @@ -467,6 +471,13 @@ void WideAngleCamera::Load() if (sdfLens->HasElement("env_texture_size")) this->dataPtr->envTextureSize = sdfLens->Get("env_texture_size"); + + const std::string envTextureFormat = "ignition:env_texture_format"; + if (sdfLens->HasElement(envTextureFormat)) + { + this->dataPtr->envCubeMapTextureFormat = static_cast( + this->OgrePixelFormat(sdfLens->Get(envTextureFormat))); + } } else this->dataPtr->lens->Load(); @@ -660,7 +671,7 @@ void WideAngleCamera::CreateEnvRenderTexture(const std::string &_textureName) this->dataPtr->envTextureSize, this->dataPtr->envTextureSize, 0, - static_cast(this->imageFormat), + this->dataPtr->envCubeMapTextureFormat, Ogre::TU_RENDERTARGET, 0, false, diff --git a/gazebo/rendering/WideAngleCameraPrivate.hh b/gazebo/rendering/WideAngleCameraPrivate.hh index cbf21c414f..dcda17c843 100644 --- a/gazebo/rendering/WideAngleCameraPrivate.hh +++ b/gazebo/rendering/WideAngleCameraPrivate.hh @@ -20,6 +20,7 @@ #include #include "gazebo/msgs/msgs.hh" +#include "gazebo/rendering/ogre_gazebo.h" #include "gazebo/util/system.hh" @@ -59,6 +60,9 @@ namespace gazebo /// \brief Viewports for the render targets public: Ogre::Viewport *envViewports[6]; + /// \brief Pixel format for cube map texture + public: Ogre::PixelFormat envCubeMapTextureFormat; + /// \brief A single cube map texture public: Ogre::Texture *envCubeMapTexture; diff --git a/test/integration/wideanglecamera_sensor.cc b/test/integration/wideanglecamera_sensor.cc index 5f6a88e9da..a714111f40 100644 --- a/test/integration/wideanglecamera_sensor.cc +++ b/test/integration/wideanglecamera_sensor.cc @@ -225,3 +225,112 @@ TEST_F(WideAngleCameraSensor, Projection) EXPECT_LT(screenPt.Z(), 1.0); #endif } + +///////////////////////////////////////////////// +TEST_F(WideAngleCameraSensor, TextureFormat) +{ +#if not defined(__APPLE__) + Load("worlds/test/issue_2928_wide_angle_camera_texture_format.world"); + + // Make sure the render engine is available. + if (rendering::RenderEngine::Instance()->GetRenderPathType() == + rendering::RenderEngine::NONE) + { + gzerr << "No rendering engine, unable to run wide angle camera test\n"; + return; + } + + const unsigned int width = 12; + const unsigned int height = 12; + + { // check camera with default texture format + sensors::SensorPtr sensor = sensors::get_sensor( + "wide_angle_camera_sensor_with_default_texture"); + sensors::WideAngleCameraSensorPtr cameraSensor = + std::dynamic_pointer_cast(sensor); + + imageCount = 0; + img = new unsigned char[width * height * 3]; + event::ConnectionPtr c = + cameraSensor->Camera()->ConnectNewImageFrame( + std::bind(&::OnNewCameraFrame, &imageCount, img, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5)); + + // Get some images + int sleep = 0; + int maxSleep = 30; + while (imageCount < 10 && sleep < maxSleep) + { + common::Time::MSleep(50); + sleep++; + } + + 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; + } + + EXPECT_NE(rSum, gSum); + EXPECT_NE(rSum, bSum); + EXPECT_NE(gSum, bSum); + + EXPECT_GT(rSum - bSum, 30000.0); + EXPECT_GT(rSum - gSum, 20000.0); + + delete [] img; + } + + { // check camera with grayscale texture format + sensors::SensorPtr sensor = sensors::get_sensor( + "wide_angle_camera_sensor_with_grayscale_texture"); + sensors::WideAngleCameraSensorPtr cameraSensor = + std::dynamic_pointer_cast(sensor); + + imageCount = 0; + img = new unsigned char[width * height * 3]; + event::ConnectionPtr c = + cameraSensor->Camera()->ConnectNewImageFrame( + std::bind(&::OnNewCameraFrame, &imageCount, img, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5)); + + // Get some images + int sleep = 0; + int maxSleep = 30; + while (imageCount < 10 && sleep < maxSleep) + { + common::Time::MSleep(50); + sleep++; + } + + 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; + } + + // For grayscale, all RGB channels should have the same value + EXPECT_EQ(rSum, gSum); + EXPECT_EQ(gSum, bSum); + EXPECT_GT(gSum, 10000u); + + delete [] img; + } +#endif +} diff --git a/worlds/test/issue_2928_wide_angle_camera_texture_format.world b/worlds/test/issue_2928_wide_angle_camera_texture_format.world new file mode 100644 index 0000000000..caf5a476fa --- /dev/null +++ b/worlds/test/issue_2928_wide_angle_camera_texture_format.world @@ -0,0 +1,140 @@ + + + + + 1 + 0 0 0 0 -0 0 + 1 1 1 1 + 0.2 0.2 0.2 1 + -1 0 -0.2 + + 10 + + + 0 + 0 + 0 + + + + 0 + + + 1 + 0.3 0 0.15 0 0 3.14159265 + + + + + 0.1 0.1 0.1 + + + + + + 1.047 + + 12 + 12 + + + 0.1 + 100 + + + gnomonical + 1 + 1.5707 + 512 + + + 1 + 10 + 1 + + + + + 1 + 0.3 2 0.15 0 0 3.14159265 + + + + + 0.1 0.1 0.1 + + + + + + 1.047 + + 12 + 12 + + + 0.1 + 100 + + + gnomonical + 1 + 1.5707 + 512 + R_FLOAT16 + + + 1 + 10 + 1 + + + + + 1 + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + + 0 0 0 0 0 0 + + + 1 + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + 10 + + + + + 10 10 10 + model://construction_cone/meshes/construction_cone.dae + + + + + 0 2 0 0 0 0 + + +