Skip to content

Commit c109df0

Browse files
committed
topic-multi property working (segfaults on close)
1 parent 92b188a commit c109df0

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>
@@ -54,6 +56,7 @@
5456
#include "rviz_common/render_panel.hpp"
5557
#include "rviz_common/validate_floats.hpp"
5658
#include "rviz_common/uniform_string_stream.hpp"
59+
#include "rviz_common/properties/ros_topic_multi_property.hpp"
5760
#include "rviz_rendering/material_manager.hpp"
5861
#include "rviz_rendering/render_window.hpp"
5962

@@ -62,6 +65,8 @@
6265
#include "rviz_default_plugins/displays/image/ros_image_texture_iface.hpp"
6366
#include "rviz_default_plugins/displays/image/get_transport_from_topic.hpp"
6467

68+
#include <rviz_common/logging.hpp> // TODO remove when done
69+
6570
namespace rviz_default_plugins
6671
{
6772
namespace displays
@@ -73,16 +78,17 @@ ImageDisplay::ImageDisplay()
7378
ImageDisplay::ImageDisplay(std::unique_ptr<ROSImageTextureIface> texture)
7479
: texture_(std::move(texture))
7580
{
81+
delete this->topic_property_;
82+
this->topic_property_ = new rviz_common::properties::RosTopicMultiProperty(
83+
"Topic",
84+
"",
85+
std::vector<QString>(),
86+
"Image transport topic to subscribe to.",
87+
this,
88+
SLOT(updateTopic()));
7689

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

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

176224
setStatus(rviz_common::properties::StatusProperty::Ok, "Topic", "OK");
177225
} catch (rclcpp::exceptions::InvalidTopicNameError & e) {
@@ -206,14 +254,6 @@ void ImageDisplay::updateNormalizeOptions()
206254
}
207255
}
208256

209-
bool ImageDisplay::setTransport(const QString & str){
210-
return image_transport_property_->setValue(str.toLower());
211-
}
212-
213-
bool ImageDisplay::setTransportStd(const std::string & std_str){
214-
return image_transport_property_->setValue(QString::fromStdString(std_str).toLower());
215-
}
216-
217257
void ImageDisplay::clear()
218258
{
219259
texture_->clear();
@@ -256,14 +296,6 @@ void ImageDisplay::reset()
256296
clear();
257297
}
258298

259-
QString ImageDisplay::getTransport(){
260-
return image_transport_property_->getString();
261-
}
262-
263-
std::string ImageDisplay::getTransportStd(){
264-
return image_transport_property_->getStdString();
265-
}
266-
267299
/* This is called by incomingMessage(). */
268300
void ImageDisplay::processMessage(sensor_msgs::msg::Image::ConstSharedPtr msg)
269301
{
@@ -279,16 +311,6 @@ void ImageDisplay::processMessage(sensor_msgs::msg::Image::ConstSharedPtr msg)
279311
texture_->addMessage(msg);
280312
}
281313

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

0 commit comments

Comments
 (0)