diff --git a/.github/ci/packages.apt b/.github/ci/packages.apt index dab47666b..936a3194c 100644 --- a/.github/ci/packages.apt +++ b/.github/ci/packages.apt @@ -4,6 +4,7 @@ libglew-dev libignition-cmake2-dev libignition-common4-dev libignition-math6-dev +libignition-math6-eigen3-dev libignition-plugin-dev libogre-1.9-dev libogre-2.2-dev diff --git a/CMakeLists.txt b/CMakeLists.txt index e8c4efa19..9b25e3492 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ option(USE_UNOFFICAL_OGRE_VERSIONS "Accept unsupported Ogre versions in the buil #-------------------------------------- # Find ignition-math -ign_find_package(ignition-math6 REQUIRED VERSION 6.6) +ign_find_package(ignition-math6 REQUIRED COMPONENTS eigen3 VERSION 6.9) set(IGN_MATH_VER ${ignition-math6_VERSION_MAJOR}) #-------------------------------------- diff --git a/include/ignition/rendering/BoundingBox.hh b/include/ignition/rendering/BoundingBox.hh new file mode 100644 index 000000000..911209c55 --- /dev/null +++ b/include/ignition/rendering/BoundingBox.hh @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 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. + * + */ +#ifndef IGNITION_RENDERING_BOUNDINGBOX_HH_ +#define IGNITION_RENDERING_BOUNDINGBOX_HH_ + +#include + +#include + +#include "ignition/rendering/config.hh" +#include "ignition/rendering/Export.hh" + +namespace ignition +{ +namespace rendering +{ +inline namespace IGNITION_RENDERING_VERSION_NAMESPACE { + class BoundingBoxPrivate; + + /// \brief 2D or 3D Bounding box. It stores the + /// position / orientation / size info of the box and its label + class IGNITION_RENDERING_VISIBLE BoundingBox + { + /// \brief Constructor + public: BoundingBox(); + + /// \brief Copy constructor + /// \param[in] _box BoundingBox to copy. + public: BoundingBox(const BoundingBox &_box); + + /// \brief Move constructor + /// \param[in] _box BoundingBox to move. + public: BoundingBox(BoundingBox &&_box) noexcept; + + /// \brief Destructor + public: virtual ~BoundingBox(); + + /// \brief Move assignment operator. + /// \param[in] _box Heightmap box to move. + /// \return Reference to this. + public: BoundingBox &operator=(BoundingBox &&_box); + + /// \brief Copy Assignment operator. + /// \param[in] _box The heightmap box to set values from. + /// \return *this + public: BoundingBox &operator=(const BoundingBox &_box); + + /// \internal + /// \brief Private data + IGN_COMMON_WARN_IGNORE__DLL_INTERFACE_MISSING + private: std::unique_ptr dataPtr; + IGN_COMMON_WARN_RESUME__DLL_INTERFACE_MISSING + }; +} +} +} +#endif diff --git a/include/ignition/rendering/BoundingBoxCamera.hh b/include/ignition/rendering/BoundingBoxCamera.hh new file mode 100644 index 000000000..51b72e2c7 --- /dev/null +++ b/include/ignition/rendering/BoundingBoxCamera.hh @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2021 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. + * + */ +#ifndef IGNITION_RENDERING_BOUNDINGBOXCAMERA_HH_ +#define IGNITION_RENDERING_BOUNDINGBOXCAMERA_HH_ + +#include +#include + +#include +#include +#include + +#include "ignition/rendering/BoundingBox.hh" +#include "ignition/rendering/Camera.hh" + +namespace ignition +{ + namespace rendering + { + inline namespace IGNITION_RENDERING_VERSION_NAMESPACE { + // + /// \brief BoundingBox types for Visible / Full 2D Boxes / 3D Boxes + enum class BoundingBoxType + { + /// 2D box that shows the full box of occluded objects + BBT_FULLBOX2D = 0, + + /// 2D box that shows the visible part of the + /// occluded object + BBT_VISIBLEBOX2D = 1, + + /// 3D oriented box + BBT_BOX3D = 2 + }; + + /// \class BoundingBoxCamera BoundingBoxCamera.hh + /// ignition/rendering/BoundingBoxCamera.hh + /// \brief Poseable BoundingBox camera used for rendering bounding boxes of + /// objects in the scene. + class IGNITION_RENDERING_VISIBLE BoundingBoxCamera : + public virtual Camera + { + /// \brief Destructor + public: virtual ~BoundingBoxCamera() { } + + /// \brief Get the BoundingBox data + /// \return Buffer of bounding boxes info (label, minX, minY, maxX, maxY) + public: virtual const std::vector &BoundingBoxData() + const = 0; + + /// \brief Connect to the new BoundingBox info + /// \param[in] _subscriber Subscriber callback function + /// \return Pointer to the new Connection. This must be kept in scope + public: virtual ignition::common::ConnectionPtr ConnectNewBoundingBoxes( + std::function &)> _subscriber) = 0; + + /// \brief Set BoundingBox Type (Visible / Full) + /// \param[in] _type BoundingBox Type (Visible / Full) + public: virtual void SetBoundingBoxType(BoundingBoxType _type) = 0; + + /// \brief Get the BoundingBox Type (Visible / Full) + /// \return BoundingBox Type (Visible / Full) + public: virtual BoundingBoxType Type() const = 0; + + /// \brief Draw a bounding box on the given image + /// \param[in] _data buffer containing the image data + /// \param[in] _color Color of the bounding box to be drawn + /// \param[in] _box bounding box to be drawn + public: virtual void DrawBoundingBox(unsigned char *_data, + const math::Color &_color, const BoundingBox &_box) const = 0; + }; + } + } +} +#endif diff --git a/include/ignition/rendering/PixelFormat.hh b/include/ignition/rendering/PixelFormat.hh index cf0832092..06f8b1dad 100644 --- a/include/ignition/rendering/PixelFormat.hh +++ b/include/ignition/rendering/PixelFormat.hh @@ -55,8 +55,10 @@ namespace ignition PF_FLOAT32_RGB = 10, // 16 bit single channel PF_L16 = 11, + /// < RGBA, 1-byte per channel + PF_R8G8B8A8 = 12, /// < Number of pixel format types - PF_COUNT = 12 + PF_COUNT = 13 }; /// \class PixelUtil PixelFormat.hh ignition/rendering/PixelFormat.hh diff --git a/include/ignition/rendering/RenderTypes.hh b/include/ignition/rendering/RenderTypes.hh index 1e2b10cd5..c7fc5dcd8 100644 --- a/include/ignition/rendering/RenderTypes.hh +++ b/include/ignition/rendering/RenderTypes.hh @@ -48,6 +48,7 @@ namespace ignition class ArrowVisual; class AxisVisual; + class BoundingBoxCamera; class Camera; class Capsule; class COMVisual; @@ -112,6 +113,10 @@ namespace ignition /// \brief Shared pointer to ThermalCamera typedef shared_ptr ThermalCameraPtr; + /// \typedef BoundingBoxCameraPtr + /// \brief Shared pointer to BoundingBoxCamera + typedef shared_ptr BoundingBoxCameraPtr; + /// \typedef SegmentationCameraPtr /// \brief Shared pointer to Segmentation Camera typedef shared_ptr SegmentationCameraPtr; @@ -282,6 +287,10 @@ namespace ignition /// \brief Shared pointer to const ThermalCamera typedef shared_ptr ConstThermalCameraPtr; + /// \typedef const BoundingBoxCameraPtr + /// \brief Shared pointer to const BoundingBox Camera + typedef shared_ptr ConstBoundingBoxCameraPtr; + /// \typedef const SegmentationCameraPtr /// \brief Shared pointer to const Segmentation Camera typedef shared_ptr ConstSegmentationCameraPtr; diff --git a/include/ignition/rendering/Scene.hh b/include/ignition/rendering/Scene.hh index bcabb856e..d88fd6bd8 100644 --- a/include/ignition/rendering/Scene.hh +++ b/include/ignition/rendering/Scene.hh @@ -679,6 +679,35 @@ namespace ignition public: virtual ThermalCameraPtr CreateThermalCamera( unsigned int _id, const std::string &_name) = 0; + /// \brief Create new BoundingBox camera. A unique ID and name will + /// automatically be assigned to the camera. + /// \return The created camera + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera() = 0; + + /// \brief Create new BoundingBox camera with the given ID. + /// A unique name will automatically be assigned to the camera. + /// If the given ID is already in use, NULL will be returned. + /// \param[in] _id ID of the new camera + /// \return The created camera + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera( + unsigned int _id) = 0; + + /// \brief Create new BoundingBox camera with the given name. + /// A unique ID will automatically be assigned to the camera. + /// If the given name is already in use, NULL will be returned. + /// \param[in] _name Name of the new camera + /// \return The created camera + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera( + const std::string &_name) = 0; + + /// \brief Create new BoundingBox camera with the given ID & name. If + /// either the given ID or name is already in use, will return NULL. + /// \param[in] _id ID of the new camera + /// \param[in] _name Name of the new camera + /// \return The created camera + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera( + unsigned int _id, const std::string &_name) = 0; + /// \brief Create new segmentation camera. A unique ID and name will /// automatically be assigned to the camera. /// \return The created camera diff --git a/include/ignition/rendering/base/BaseBoundingBoxCamera.hh b/include/ignition/rendering/base/BaseBoundingBoxCamera.hh new file mode 100644 index 000000000..3fcf6f69b --- /dev/null +++ b/include/ignition/rendering/base/BaseBoundingBoxCamera.hh @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2021 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. + * + */ +#ifndef IGNITION_RENDERING_BASE_BASEBOUNDINGBOXCAMERA_HH_ +#define IGNITION_RENDERING_BASE_BASEBOUNDINGBOXCAMERA_HH_ + +#include + +#include +#include + +#include "ignition/rendering/base/BaseCamera.hh" +#include "ignition/rendering/BoundingBoxCamera.hh" + +namespace ignition +{ + namespace rendering + { + inline namespace IGNITION_RENDERING_VERSION_NAMESPACE { + + template + class BaseBoundingBoxCamera: + public virtual BoundingBoxCamera, + public virtual BaseCamera, + public virtual T + { + /// \brief Constructor + protected: BaseBoundingBoxCamera(); + + /// \brief Destructor + public: virtual ~BaseBoundingBoxCamera(); + + // Documentation inherited + public: virtual const std::vector &BoundingBoxData() const; + + // Documentation inherited + public: virtual ignition::common::ConnectionPtr ConnectNewBoundingBoxes( + std::function &)> _subscriber) = 0; + + // Documentation inherited + public: virtual void SetBoundingBoxType(BoundingBoxType _type); + + // Documentation inherited + public: virtual BoundingBoxType Type() const; + + // Documentation inherited + public: virtual void DrawBoundingBox(unsigned char *_data, + const math::Color &_color, const BoundingBox &_box) const = 0; + + /// \brief The bounding box type + protected: BoundingBoxType type = BoundingBoxType::BBT_FULLBOX2D; + + /// \brief The bounding box data + protected: std::vector boundingBoxes; + }; + + ////////////////////////////////////////////////// + template + BaseBoundingBoxCamera::BaseBoundingBoxCamera() + { + } + + ////////////////////////////////////////////////// + template + BaseBoundingBoxCamera::~BaseBoundingBoxCamera() + { + } + + ////////////////////////////////////////////////// + template + const std::vector & + BaseBoundingBoxCamera::BoundingBoxData() const + { + return this->boundingBoxes; + } + + ////////////////////////////////////////////////// + template + void BaseBoundingBoxCamera::SetBoundingBoxType(BoundingBoxType _type) + { + this->type = _type; + } + + ////////////////////////////////////////////////// + template + BoundingBoxType BaseBoundingBoxCamera::Type() const + { + return this->type; + } + } + } +} +#endif diff --git a/include/ignition/rendering/base/BaseScene.hh b/include/ignition/rendering/base/BaseScene.hh index 8093e249e..29d30a015 100644 --- a/include/ignition/rendering/base/BaseScene.hh +++ b/include/ignition/rendering/base/BaseScene.hh @@ -338,6 +338,21 @@ namespace ignition public: virtual ThermalCameraPtr CreateThermalCamera( const unsigned int _id, const std::string &_name) override; + // Documentation inherited. + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera() override; + + // Documentation inherited. + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera( + const unsigned int _id) override; + + // Documentation inherited. + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera( + const std::string &_name) override; + + // Documentation inherited. + public: virtual BoundingBoxCameraPtr CreateBoundingBoxCamera( + const unsigned int _id, const std::string &_name) override; + // Documentation inherited. public: virtual SegmentationCameraPtr CreateSegmentationCamera() override; @@ -615,6 +630,21 @@ namespace ignition return ThermalCameraPtr(); } + /// \brief Implementation for creating a BoundingBox camera. + /// \param[in] _id Unique id + /// \param[in] _name Name of BoundingBox camera + /// \return Pointer to BoundingBox camera + protected: virtual BoundingBoxCameraPtr CreateBoundingBoxCameraImpl( + unsigned int _id, const std::string &_name) + { + // The following two lines will avoid doxygen warnings + (void)_id; + (void)_name; + ignerr << "BoundingBox camera not supported by: " + << this->Engine()->Name() << std::endl; + return BoundingBoxCameraPtr(); + } + /// \brief Implementation for creating a segmentation camera. /// \param[in] _id Unique id /// \param[in] _name Name of segmentation camera diff --git a/src/BoundingBox.cc b/src/BoundingBox.cc new file mode 100644 index 000000000..505ec5b00 --- /dev/null +++ b/src/BoundingBox.cc @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021 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 "ignition/rendering/BoundingBox.hh" + +using namespace ignition; +using namespace rendering; + +////////////////////////////////////////////////// +class ignition::rendering::BoundingBoxPrivate +{ +}; + +////////////////////////////////////////////////// +BoundingBox::BoundingBox() : + dataPtr(std::make_unique()) +{ +} + +///////////////////////////////////////////////// +BoundingBox::~BoundingBox() +{ +} + +////////////////////////////////////////////////// +BoundingBox::BoundingBox(const BoundingBox &_texture) + : dataPtr(std::make_unique(*_texture.dataPtr)) +{ +} + +////////////////////////////////////////////////// +BoundingBox::BoundingBox(BoundingBox &&_texture) noexcept + : dataPtr(std::exchange(_texture.dataPtr, nullptr)) +{ +} + +///////////////////////////////////////////////// +BoundingBox &BoundingBox::operator=( + const BoundingBox &_texture) +{ + return *this = BoundingBox(_texture); +} + +///////////////////////////////////////////////// +BoundingBox &BoundingBox::operator=(BoundingBox &&_texture) +{ + std::swap(this->dataPtr, _texture.dataPtr); + return *this; +} + diff --git a/src/BoundingBox_TEST.cc b/src/BoundingBox_TEST.cc new file mode 100644 index 000000000..d4ee62aab --- /dev/null +++ b/src/BoundingBox_TEST.cc @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2021 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 + +#include "test_config.h" // NOLINT(build/include) +#include "ignition/rendering/BoundingBox.hh" + +using namespace ignition; +using namespace rendering; + +class BoundingBoxTest : public testing::Test +{ +}; + +///////////////////////////////////////////////// +TEST(BoundingBoxTest, BoundingBox) +{ + BoundingBox box; +} + +///////////////////////////////////////////////// +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/PixelFormat.cc b/src/PixelFormat.cc index 1d42c0531..9fc1f0829 100644 --- a/src/PixelFormat.cc +++ b/src/PixelFormat.cc @@ -36,7 +36,8 @@ const char *PixelUtil::names[PF_COUNT] = "FLOAT32_R", "FLOAT32_RGBA", "FLOAT32_RGB", - "L16" + "L16", + "R8G8B8A8" }; ////////////////////////////////////////////////// @@ -65,7 +66,9 @@ const unsigned char PixelUtil::channelCounts[PF_COUNT] = // PF_FLOAT32_RGB 3, // PF_L16 - 1 + 1, + // PG_R8G8B8A8 + 4 }; ////////////////////////////////////////////////// @@ -95,6 +98,8 @@ const unsigned char PixelUtil::channelByteCounts[PF_COUNT] = 4, // PF_L16 2, + // PF_R8G8B8A8 + 1 }; ////////////////////////////////////////////////// diff --git a/src/PixelFormat_TEST.cc b/src/PixelFormat_TEST.cc index ab95b89b2..622bf442e 100644 --- a/src/PixelFormat_TEST.cc +++ b/src/PixelFormat_TEST.cc @@ -51,6 +51,11 @@ TEST(PixelFormatTest, PixelUtil) EXPECT_EQ(2u, PixelUtil::BytesPerPixel(format)); EXPECT_EQ(2u, PixelUtil::BytesPerChannel(format)); EXPECT_EQ(2048u, PixelUtil::MemorySize(format, 32, 32)); + + format = PF_R8G8B8A8; + EXPECT_EQ(4u, PixelUtil::BytesPerPixel(format)); + EXPECT_EQ(1u, PixelUtil::BytesPerChannel(format)); + EXPECT_EQ(4096u, PixelUtil::MemorySize(format, 32, 32)); } int main(int argc, char **argv) diff --git a/src/base/BaseScene.cc b/src/base/BaseScene.cc index 1aa14427e..775dec699 100644 --- a/src/base/BaseScene.cc +++ b/src/base/BaseScene.cc @@ -27,6 +27,7 @@ #include "ignition/rendering/ArrowVisual.hh" #include "ignition/rendering/AxisVisual.hh" +#include "ignition/rendering/BoundingBoxCamera.hh" #include "ignition/rendering/COMVisual.hh" #include "ignition/rendering/InertiaVisual.hh" #include "ignition/rendering/JointVisual.hh" @@ -815,6 +816,36 @@ ThermalCameraPtr BaseScene::CreateThermalCamera(const unsigned int _id, return (result) ? camera : nullptr; } +////////////////////////////////////////////////// +BoundingBoxCameraPtr BaseScene::CreateBoundingBoxCamera() +{ + unsigned int objId = this->CreateObjectId(); + return this->CreateBoundingBoxCamera(objId); +} +////////////////////////////////////////////////// +BoundingBoxCameraPtr BaseScene::CreateBoundingBoxCamera( + const unsigned int _id) +{ + std::string objName = this->CreateObjectName(_id, "BoundingBoxCamera"); + return this->CreateBoundingBoxCamera(_id, objName); +} +////////////////////////////////////////////////// +BoundingBoxCameraPtr BaseScene::CreateBoundingBoxCamera( + const std::string &_name) +{ + unsigned int objId = this->CreateObjectId(); + return this->CreateBoundingBoxCamera(objId, _name); +} +////////////////////////////////////////////////// +BoundingBoxCameraPtr BaseScene::CreateBoundingBoxCamera( + const unsigned int _id, + const std::string &_name) +{ + BoundingBoxCameraPtr camera = this->CreateBoundingBoxCameraImpl(_id, _name); + bool result = this->RegisterSensor(camera); + return (result) ? camera : nullptr; +} + ////////////////////////////////////////////////// SegmentationCameraPtr BaseScene::CreateSegmentationCamera() {