Skip to content

Commit 3f3296d

Browse files
committed
topic-multi property working (segfaults on close)
1 parent d2e3289 commit 3f3296d

File tree

5 files changed

+90
-59
lines changed

5 files changed

+90
-59
lines changed

rviz_common/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ set(rviz_common_headers_to_moc
104104
include/rviz_common/properties/property_tree_with_help.hpp
105105
include/rviz_common/properties/qos_profile_property.hpp
106106
include/rviz_common/properties/ros_topic_property.hpp
107+
include/rviz_common/properties/ros_topic_multi_property.hpp
107108
include/rviz_common/properties/status_list.hpp
108109
include/rviz_common/properties/status_property.hpp
109110
include/rviz_common/properties/string_property.hpp
@@ -183,6 +184,7 @@ set(rviz_common_source_files
183184
src/rviz_common/properties/property_tree_with_help.cpp
184185
src/rviz_common/properties/property.cpp
185186
src/rviz_common/properties/ros_topic_property.cpp
187+
src/rviz_common/properties/ros_topic_multi_property.cpp
186188
src/rviz_common/properties/quaternion_property.cpp
187189
src/rviz_common/properties/qos_profile_property.cpp
188190
src/rviz_common/properties/regex_filter_property.cpp

rviz_common/include/rviz_common/properties/ros_topic_multi_property.hpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#define RVIZ_COMMON__PROPERTIES__ROS_TOPIC_MULTI_PROPERTY_HPP_
3232

3333
#include <string>
34-
#include <unordered_set>
34+
#include <vector>
3535

3636
#include "rviz_common/properties/ros_topic_property.hpp"
3737
#include "rviz_common/ros_integration/ros_node_abstraction_iface.hpp"
@@ -46,21 +46,30 @@ class RVIZ_COMMON_PUBLIC RosTopicMultiProperty : public RosTopicProperty
4646
{
4747
Q_OBJECT
4848
public:
49+
explicit RosTopicMultiProperty(
50+
const QString & name = QString(),
51+
const QString & default_value = QString(),
52+
const std::vector<QString> & message_types = std::vector<QString>(),
53+
const QString & description = QString(),
54+
Property * parent = nullptr,
55+
const char * changed_slot = nullptr,
56+
QObject * receiver = nullptr);
4957

50-
void setMessageTypes(const std::unordered_set<QString> & message_types);
58+
void setMessageTypes(const std::vector<QString> & message_types);
5159

52-
std::unordered_set<QString> getMessageTypes() const
60+
std::vector<QString> getMessageTypes() const
5361
{return message_types_;}
5462

5563
protected Q_SLOTS:
5664
virtual void fillTopicList() override;
5765

5866
private:
59-
// hide the parent class methods which only take a single type
67+
// Hide the parent class methods which only take a single type
6068
using RosTopicProperty::setMessageType;
6169
using RosTopicProperty::getMessageType;
6270

63-
std::unordered_set<QString> message_types_; // TODO is there a QT-friendly type?
71+
// Instead of one message type, store a list of allowed types
72+
std::vector<QString> message_types_;
6473
};
6574

6675
} // end namespace properties

rviz_common/src/rviz_common/properties/ros_topic_multi_property.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <map>
3232
#include <string>
33+
#include <algorithm>
3334

3435
#include <QApplication> // NOLINT: cpplint can't handle Qt imports
3536

@@ -41,7 +42,19 @@ namespace rviz_common
4142
namespace properties
4243
{
4344

44-
void RosTopicMultiProperty::setMessageTypes(const std::unordered_set<QString> & message_types)
45+
RosTopicMultiProperty::RosTopicMultiProperty(
46+
const QString & name,
47+
const QString & default_value,
48+
const std::vector<QString> & message_types,
49+
const QString & description,
50+
Property * parent,
51+
const char * changed_slot,
52+
QObject * receiver)
53+
: RosTopicProperty(name, default_value, "", description, parent, changed_slot, receiver),
54+
message_types_(message_types)
55+
{}
56+
57+
void RosTopicMultiProperty::setMessageTypes(const std::vector<QString> & message_types)
4558
{
4659
message_types_ = message_types;
4760
}
@@ -57,9 +70,9 @@ void RosTopicMultiProperty::fillTopicList()
5770
for (const auto & topic : published_topics) {
5871
// Only add topics whose type matches.
5972
for (const auto & type : topic.second) {
60-
if (message_types_.find(QString::fromStdString(type)) != message_types_.end()) {
73+
if (std::find(message_types_.begin(), message_types_.end(), QString::fromStdString(type))
74+
!= message_types_.end())
6175
addOptionStd(topic.first);
62-
}
6376
}
6477
}
6578
sortOptions();

rviz_default_plugins/include/rviz_default_plugins/displays/image/image_display.hpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,13 @@ class RVIZ_DEFAULT_PLUGINS_PUBLIC ImageDisplay : public
8585
ImageDisplay();
8686
~ImageDisplay() override;
8787

88-
// Overrides from Display
8988
void onInitialize() override;
9089
void update(float wall_dt, float ros_dt) override;
9190
void reset() override;
9291

93-
QString getTransport();
94-
std::string getTransportStd();
9592

9693
public Q_SLOTS:
9794
virtual void updateNormalizeOptions();
98-
bool setTransport(const QString & str);
99-
bool setTransportStd(const std::string & std_str);
10095

10196
protected:
10297
// overrides from Display
@@ -111,16 +106,6 @@ public Q_SLOTS:
111106
void processMessage(sensor_msgs::msg::Image::ConstSharedPtr msg) override;
112107

113108
image_transport::Subscriber subscription_;
114-
rviz_common::properties::EnumProperty* image_transport_property_;
115-
const std::unordered_map<QString, QString> transport_message_types_ =
116-
{
117-
{"raw", QString::fromStdString(rosidl_generator_traits::name<sensor_msgs::msg::Image>())},
118-
{"compressed", QString::fromStdString(rosidl_generator_traits::name<sensor_msgs::msg::CompressedImage>())},
119-
/*{"theora", QString::fromStdString(rosidl_generator_traits::name<theora_image_transport::msg::Packet>())}*/
120-
};
121-
122-
protected Q_SLOTS:
123-
void updateTransport();
124109

125110
private:
126111
void setupScreenRectangle();

rviz_default_plugins/src/rviz_default_plugins/displays/image/image_display.cpp

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <memory>
3333
#include <string>
3434
#include <utility>
35+
#include <algorithm>
36+
#include <vector>
3537

3638
#include <OgreCamera.h>
3739
#include <OgreManualObject.h>
@@ -56,6 +58,7 @@
5658
#include "rviz_common/render_panel.hpp"
5759
#include "rviz_common/validate_floats.hpp"
5860
#include "rviz_common/uniform_string_stream.hpp"
61+
#include "rviz_common/properties/ros_topic_multi_property.hpp"
5962
#include "rviz_rendering/material_manager.hpp"
6063
#include "rviz_rendering/render_window.hpp"
6164

@@ -64,6 +67,8 @@
6467
#include "rviz_default_plugins/displays/image/ros_image_texture_iface.hpp"
6568
#include "rviz_default_plugins/displays/image/get_transport_from_topic.hpp"
6669

70+
#include <rviz_common/logging.hpp> // TODO remove when done
71+
6772
namespace rviz_default_plugins
6873
{
6974
namespace displays
@@ -75,16 +80,17 @@ ImageDisplay::ImageDisplay()
7580
ImageDisplay::ImageDisplay(std::unique_ptr<ROSImageTextureIface> texture)
7681
: texture_(std::move(texture))
7782
{
83+
delete this->topic_property_;
84+
this->topic_property_ = new rviz_common::properties::RosTopicMultiProperty(
85+
"Topic",
86+
"",
87+
std::vector<QString>(),
88+
"Image transport topic to subscribe to.",
89+
this,
90+
SLOT(updateTopic()));
7891

79-
image_transport_property_ = new rviz_common::properties::EnumProperty(
80-
"Image Transport Hint",
81-
"raw",
82-
"What type of image transport to use.",
83-
topic_property_, SLOT(updateTransport()),
84-
this);
85-
86-
for (const auto& [key, value] : transport_message_types_)
87-
image_transport_property_->addOption(key);
92+
delete this->qos_profile_property_;
93+
this->qos_profile_property_ = new rviz_common::properties::QosProfileProperty(this->topic_property_, rclcpp::QoS(5));
8894

8995
normalize_property_ = new rviz_common::properties::BoolProperty(
9096
"Normalize Range",
@@ -154,6 +160,45 @@ void ImageDisplay::subscribe(){
154160
if (!isEnabled()) {
155161
return;
156162
}
163+
164+
// TODO this should really be in onInitialize but setStatus does not work there
165+
// Populate topic message types based on installed image_transport plugins
166+
image_transport::ImageTransport image_transport_(rviz_ros_node_.lock()->get_raw_node());
167+
std::vector<std::string> transports = image_transport_.getLoadableTransports();
168+
std::vector<QString> message_types;
169+
// Map to message types
170+
const std::unordered_map<std::string, std::string> transport_message_types_ =
171+
{
172+
{"raw", "sensor_msgs/msg/Image"},
173+
{"compressed", "sensor_msgs/msg/CompressedImage"},
174+
{"compressedDepth", "sensor_msgs/msg/CompressedImage"},
175+
{"theora", "theora_image_transport/msg/Packet"},
176+
{"zstd", "sensor_msgs/msg/CompressedImage"},
177+
};
178+
std::string transports_str = "";
179+
rviz_common::properties::StatusProperty::Level transports_status_level =
180+
rviz_common::properties::StatusProperty::Ok;
181+
for (std::string & transport : transports){
182+
transport = transport.substr(transport.find_last_of('/') + 1);
183+
try{
184+
message_types.push_back(QString::fromStdString(transport_message_types_.at(transport)));
185+
transports_str += transport + ", ";
186+
}
187+
catch (const std::out_of_range & e){
188+
transports_status_level = rviz_common::properties::StatusProperty::Warn;
189+
transports_str += "(unknown: " + transport + "), ";
190+
}
191+
}
192+
setStatusStd(
193+
transports_status_level,
194+
"Image Transports",
195+
transports_str);
196+
// Remove duplicates
197+
message_types.erase(std::unique(message_types.begin(), message_types.end() ), message_types.end());
198+
// Update the message types to allow in the topic_property_
199+
((rviz_common::properties::RosTopicMultiProperty*)topic_property_)->setMessageTypes(message_types);
200+
201+
RVIZ_COMMON_LOG_INFO("subscribe");
157202
if (topic_property_->isEmpty()) {
158203
setStatus(
159204
rviz_common::properties::StatusProperty::Error, "Topic",
@@ -173,7 +218,10 @@ void ImageDisplay::subscribe(){
173218
(uint32_t)qos_profile.get_rmw_qos_profile().depth, // TODO try without cast
174219
&ImageDisplay::incomingMessage,
175220
this,
176-
new image_transport::TransportHints(node.get(),getTransportStd(),"image_transport"));
221+
new image_transport::TransportHints(
222+
node.get(),
223+
getTransportFromTopic(topic_property_->getStdString()),
224+
"image_transport"));
177225

178226
setStatus(rviz_common::properties::StatusProperty::Ok, "Topic", "OK");
179227
} catch (rclcpp::exceptions::InvalidTopicNameError & e) {
@@ -208,14 +256,6 @@ void ImageDisplay::updateNormalizeOptions()
208256
}
209257
}
210258

211-
bool ImageDisplay::setTransport(const QString & str){
212-
return image_transport_property_->setValue(str.toLower());
213-
}
214-
215-
bool ImageDisplay::setTransportStd(const std::string & std_str){
216-
return image_transport_property_->setValue(QString::fromStdString(std_str).toLower());
217-
}
218-
219259
void ImageDisplay::clear()
220260
{
221261
texture_->clear();
@@ -258,14 +298,6 @@ void ImageDisplay::reset()
258298
clear();
259299
}
260300

261-
QString ImageDisplay::getTransport(){
262-
return image_transport_property_->getString();
263-
}
264-
265-
std::string ImageDisplay::getTransportStd(){
266-
return image_transport_property_->getStdString();
267-
}
268-
269301
/* This is called by incomingMessage(). */
270302
void ImageDisplay::processMessage(sensor_msgs::msg::Image::ConstSharedPtr msg)
271303
{
@@ -281,16 +313,6 @@ void ImageDisplay::processMessage(sensor_msgs::msg::Image::ConstSharedPtr msg)
281313
texture_->addMessage(msg);
282314
}
283315

284-
void ImageDisplay::updateTransport(){
285-
topic_property_->setMessageType(
286-
transport_message_types_.at(image_transport_property_->getString()));
287-
288-
// If topic does not match desired transport, clear it.
289-
if (getTransportFromTopic(topic_property_->getStdString()) !=
290-
image_transport_property_->getStdString())
291-
topic_property_->setString("");
292-
}
293-
294316
void ImageDisplay::setupScreenRectangle()
295317
{
296318
static int count = 0;

0 commit comments

Comments
 (0)