Skip to content

Commit ff7e705

Browse files
committed
feat(rviz): add topic text overlay plugin
1 parent 331eae6 commit ff7e705

7 files changed

Lines changed: 1402 additions & 0 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
project(autoware_topic_text_overlay_rviz_plugin)
3+
4+
find_package(autoware_cmake REQUIRED)
5+
autoware_package()
6+
7+
find_package(Qt5 REQUIRED Core Widgets)
8+
set(QT_LIBRARIES Qt5::Widgets)
9+
set(CMAKE_AUTOMOC ON)
10+
set(CMAKE_INCLUDE_CURRENT_DIR ON)
11+
add_definitions(-DQT_NO_KEYWORDS)
12+
13+
ament_auto_add_library(${PROJECT_NAME} SHARED
14+
DIRECTORY src
15+
)
16+
17+
target_link_libraries(${PROJECT_NAME}
18+
${QT_LIBRARIES}
19+
)
20+
21+
pluginlib_export_plugin_description_file(rviz_common plugins/plugins_description.xml)
22+
23+
ament_auto_package(
24+
INSTALL_TO_SHARE
25+
plugins
26+
)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>autoware_topic_text_overlay_rviz_plugin</name>
5+
<version>0.1.0</version>
6+
<description>RViz panel plugin for overlaying selected text topics in the 3D view.</description>
7+
8+
<maintainer email="satoshi.ota@tier4.jp">Satoshi Ota</maintainer>
9+
10+
<license>Apache License 2.0</license>
11+
<license>BSD-3-Clause</license>
12+
13+
<buildtool_depend>ament_cmake_auto</buildtool_depend>
14+
<buildtool_depend>autoware_cmake</buildtool_depend>
15+
16+
<depend>autoware_internal_debug_msgs</depend>
17+
<depend>pluginlib</depend>
18+
<depend>rclcpp</depend>
19+
<depend>rviz_common</depend>
20+
<depend>rviz_ogre_vendor</depend>
21+
<depend>rviz_rendering</depend>
22+
<depend>tier4_debug_msgs</depend>
23+
<depend>visualization_msgs</depend>
24+
25+
<test_depend>ament_lint_auto</test_depend>
26+
<test_depend>autoware_lint_common</test_depend>
27+
28+
<export>
29+
<build_type>ament_cmake</build_type>
30+
</export>
31+
</package>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<library path="autoware_topic_text_overlay_rviz_plugin">
2+
<class name="autoware_topic_text_overlay_rviz_plugin/TopicTextOverlayPanel"
3+
type="autoware::topic_text_overlay_rviz_plugin::TopicTextOverlayPanel"
4+
base_class_type="rviz_common::Panel">
5+
<description>Panel for overlaying selected StringStamped, Marker, and MarkerArray text topics.</description>
6+
</class>
7+
</library>
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// Copyright 2024 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Copyright (c) 2014, JSK Lab
16+
// All rights reserved.
17+
//
18+
// Software License Agreement (BSD License)
19+
//
20+
// Redistribution and use in source and binary forms, with or without
21+
// modification, are permitted provided that the following conditions
22+
// are met:
23+
//
24+
// * Redistributions of source code must retain the above copyright
25+
// notice, this list of conditions and the following disclaimer.
26+
// * Redistributions in binary form must reproduce the above
27+
// copyright notice, this list of conditions and the following
28+
// disclaimer in the documentation and/or other materials provided
29+
// with the distribution.
30+
// * Neither the name of {copyright_holder} nor the names of its
31+
// contributors may be used to endorse or promote products derived
32+
// from this software without specific prior written permission.
33+
//
34+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45+
46+
#include "jsk_overlay_utils.hpp"
47+
48+
#include <rviz_rendering/render_system.hpp>
49+
50+
#include <cstring>
51+
#include <string>
52+
#include <utility>
53+
54+
namespace autoware::topic_text_overlay_rviz_plugin
55+
{
56+
ScopedPixelBuffer::ScopedPixelBuffer(Ogre::HardwarePixelBufferSharedPtr pixel_buffer)
57+
: pixel_buffer_(std::move(pixel_buffer))
58+
{
59+
pixel_buffer_->lock(Ogre::HardwareBuffer::HBL_NORMAL);
60+
}
61+
62+
ScopedPixelBuffer::~ScopedPixelBuffer()
63+
{
64+
pixel_buffer_->unlock();
65+
}
66+
67+
QImage ScopedPixelBuffer::getQImage(const unsigned int width, const unsigned int height)
68+
{
69+
const Ogre::PixelBox & pixel_box = pixel_buffer_->getCurrentLock();
70+
auto * destination = static_cast<Ogre::uint8 *>(pixel_box.data);
71+
std::memset(destination, 0, width * height * 4);
72+
return QImage(destination, width, height, QImage::Format_ARGB32);
73+
}
74+
75+
QImage ScopedPixelBuffer::getQImage(OverlayObject & overlay)
76+
{
77+
return getQImage(overlay.getTextureWidth(), overlay.getTextureHeight());
78+
}
79+
80+
OverlayObject::OverlayObject(
81+
Ogre::SceneManager * manager, rclcpp::Logger logger, const std::string & name)
82+
: name_(name), logger_(logger)
83+
{
84+
rviz_rendering::RenderSystem::get()->prepareOverlays(manager);
85+
const std::string material_name = name_ + "Material";
86+
auto * overlay_manager = Ogre::OverlayManager::getSingletonPtr();
87+
overlay_ = overlay_manager->create(name_);
88+
panel_ = static_cast<Ogre::PanelOverlayElement *>(
89+
overlay_manager->createOverlayElement("Panel", name_ + "Panel"));
90+
panel_->setMetricsMode(Ogre::GMM_PIXELS);
91+
92+
panel_material_ = Ogre::MaterialManager::getSingleton().create(
93+
material_name, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
94+
panel_->setMaterialName(panel_material_->getName());
95+
overlay_->add2D(panel_);
96+
}
97+
98+
OverlayObject::~OverlayObject()
99+
{
100+
hide();
101+
panel_material_->unload();
102+
Ogre::MaterialManager::getSingleton().remove(panel_material_->getName());
103+
}
104+
105+
void OverlayObject::hide()
106+
{
107+
if (overlay_->isVisible()) {
108+
overlay_->hide();
109+
}
110+
}
111+
112+
void OverlayObject::show()
113+
{
114+
if (!overlay_->isVisible()) {
115+
overlay_->show();
116+
}
117+
}
118+
119+
bool OverlayObject::isTextureReady()
120+
{
121+
return static_cast<bool>(texture_);
122+
}
123+
124+
void OverlayObject::updateTextureSize(unsigned int width, unsigned int height)
125+
{
126+
const std::string texture_name = name_ + "Texture";
127+
if (width == 0) {
128+
RCLCPP_WARN(logger_, "width=0 is specified as texture size");
129+
width = 1;
130+
}
131+
if (height == 0) {
132+
RCLCPP_WARN(logger_, "height=0 is specified as texture size");
133+
height = 1;
134+
}
135+
if (!isTextureReady() || width != texture_->getWidth() || height != texture_->getHeight()) {
136+
if (isTextureReady()) {
137+
Ogre::TextureManager::getSingleton().remove(texture_name);
138+
panel_material_->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
139+
}
140+
texture_ = Ogre::TextureManager::getSingleton().createManual(
141+
texture_name, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
142+
width, height, 0, Ogre::PF_A8R8G8B8, Ogre::TU_DEFAULT);
143+
panel_material_->getTechnique(0)->getPass(0)->createTextureUnitState(texture_name);
144+
panel_material_->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
145+
}
146+
}
147+
148+
ScopedPixelBuffer OverlayObject::getBuffer()
149+
{
150+
return ScopedPixelBuffer(texture_->getBuffer());
151+
}
152+
153+
void OverlayObject::setPosition(const double left, const double top)
154+
{
155+
panel_->setPosition(left, top);
156+
}
157+
158+
void OverlayObject::setDimensions(const double width, const double height)
159+
{
160+
panel_->setDimensions(width, height);
161+
}
162+
163+
unsigned int OverlayObject::getTextureWidth()
164+
{
165+
return isTextureReady() ? texture_->getWidth() : 0;
166+
}
167+
168+
unsigned int OverlayObject::getTextureHeight()
169+
{
170+
return isTextureReady() ? texture_->getHeight() : 0;
171+
}
172+
} // namespace autoware::topic_text_overlay_rviz_plugin
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright 2024 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Copyright (c) 2014, JSK Lab
16+
// All rights reserved.
17+
//
18+
// Software License Agreement (BSD License)
19+
//
20+
// Redistribution and use in source and binary forms, with or without
21+
// modification, are permitted provided that the following conditions
22+
// are met:
23+
//
24+
// * Redistributions of source code must retain the above copyright
25+
// notice, this list of conditions and the following disclaimer.
26+
// * Redistributions in binary form must reproduce the above
27+
// copyright notice, this list of conditions and the following
28+
// disclaimer in the documentation and/or other materials provided
29+
// with the distribution.
30+
// * Neither the name of {copyright_holder} nor the names of its
31+
// contributors may be used to endorse or promote products derived
32+
// from this software without specific prior written permission.
33+
//
34+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45+
46+
#ifndef AUTOWARE_TOPIC_TEXT_OVERLAY_RVIZ_PLUGIN__JSK_OVERLAY_UTILS_HPP_
47+
#define AUTOWARE_TOPIC_TEXT_OVERLAY_RVIZ_PLUGIN__JSK_OVERLAY_UTILS_HPP_
48+
49+
#include <OgreHardwarePixelBuffer.h>
50+
#include <OgreMaterialManager.h>
51+
#include <OgreSceneManager.h>
52+
#include <OgreTechnique.h>
53+
#include <OgreTexture.h>
54+
#include <OgreTextureManager.h>
55+
56+
#include <memory>
57+
#include <string>
58+
59+
#if OGRE_VERSION < ((1 << 16) | (9 << 8) | 0)
60+
#include <OGRE/OgreOverlay.h>
61+
#include <OGRE/OgreOverlayContainer.h>
62+
#include <OGRE/OgreOverlayElement.h>
63+
#include <OGRE/OgreOverlayManager.h>
64+
#include <OGRE/OgrePanelOverlayElement.h>
65+
#else
66+
#include <Overlay/OgreOverlay.h>
67+
#include <Overlay/OgreOverlayContainer.h>
68+
#include <Overlay/OgreOverlayElement.h>
69+
#include <Overlay/OgreOverlayManager.h>
70+
#include <Overlay/OgrePanelOverlayElement.h>
71+
#endif
72+
73+
#include <QColor>
74+
#include <QImage>
75+
#include <rclcpp/rclcpp.hpp>
76+
77+
namespace autoware::topic_text_overlay_rviz_plugin
78+
{
79+
class OverlayObject;
80+
81+
class ScopedPixelBuffer
82+
{
83+
public:
84+
explicit ScopedPixelBuffer(Ogre::HardwarePixelBufferSharedPtr pixel_buffer);
85+
~ScopedPixelBuffer();
86+
87+
QImage getQImage(unsigned int width, unsigned int height);
88+
QImage getQImage(OverlayObject & overlay);
89+
90+
private:
91+
Ogre::HardwarePixelBufferSharedPtr pixel_buffer_;
92+
};
93+
94+
class OverlayObject
95+
{
96+
public:
97+
using Ptr = std::shared_ptr<OverlayObject>;
98+
99+
OverlayObject(Ogre::SceneManager * manager, rclcpp::Logger logger, const std::string & name);
100+
~OverlayObject();
101+
102+
void hide();
103+
void show();
104+
bool isTextureReady();
105+
void updateTextureSize(unsigned int width, unsigned int height);
106+
ScopedPixelBuffer getBuffer();
107+
void setPosition(double left, double top);
108+
void setDimensions(double width, double height);
109+
unsigned int getTextureWidth();
110+
unsigned int getTextureHeight();
111+
112+
private:
113+
const std::string name_;
114+
rclcpp::Logger logger_;
115+
Ogre::Overlay * overlay_;
116+
Ogre::PanelOverlayElement * panel_;
117+
Ogre::MaterialPtr panel_material_;
118+
Ogre::TexturePtr texture_;
119+
};
120+
} // namespace autoware::topic_text_overlay_rviz_plugin
121+
122+
#endif // AUTOWARE_TOPIC_TEXT_OVERLAY_RVIZ_PLUGIN__JSK_OVERLAY_UTILS_HPP_

0 commit comments

Comments
 (0)