Skip to content

Commit 74020ce

Browse files
authored
Extend the message filter display for point cloud 2 display (#1566)
1 parent fcb75e1 commit 74020ce

File tree

2 files changed

+38
-150
lines changed

2 files changed

+38
-150
lines changed

rviz_default_plugins/include/rviz_default_plugins/displays/pointcloud/point_cloud2_display.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ struct Offsets
5858
uint32_t x, y, z;
5959
};
6060

61-
// TODO(greimela) This display originally extended the MessageFilterDisplay. Revisit when available
6261
/**
6362
* \class PointCloud2Display
6463
* \brief Displays a point cloud of type sensor_msgs::PointCloud2

rviz_default_plugins/include/rviz_default_plugins/displays/pointcloud/point_cloud_transport_display.hpp

Lines changed: 38 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2828
// POSSIBILITY OF SUCH DAMAGE.
2929

30-
3130
#ifndef RVIZ_DEFAULT_PLUGINS__DISPLAYS__POINTCLOUD__POINT_CLOUD_TRANSPORT_DISPLAY_HPP_
3231
#define RVIZ_DEFAULT_PLUGINS__DISPLAYS__POINTCLOUD__POINT_CLOUD_TRANSPORT_DISPLAY_HPP_
3332

@@ -39,186 +38,76 @@
3938
#include "get_transport_from_topic.hpp"
4039
#include "point_cloud_transport/point_cloud_transport.hpp"
4140
#include "point_cloud_transport/subscriber_filter.hpp"
42-
#include "rviz_common/ros_topic_display.hpp"
41+
#include "rviz_common/message_filter_display.hpp"
4342

4443
namespace rviz_default_plugins
4544
{
4645
namespace displays
4746
{
4847

4948
template<class MessageType>
50-
class PointCloud2TransportDisplay : public rviz_common::_RosTopicDisplay
49+
class PointCloud2TransportDisplay : public rviz_common::MessageFilterDisplay<MessageType>
5150
{
52-
// No Q_OBJECT macro here, moc does not support Q_OBJECT in a templated class.
51+
// No Q_OBJECT macro here, moc does not support Q_OBJECT in a templated class.
5352

5453
public:
55-
/// Convenience typedef so subclasses don't have to use
56-
/// the long templated class name to refer to their super class.
54+
/// Convenience typedef so subclasses don't have to use
55+
/// the long templated class name to refer to their super class.
5756
typedef PointCloud2TransportDisplay<MessageType> PC2RDClass;
5857

59-
PointCloud2TransportDisplay()
60-
: messages_received_(0)
61-
{
62-
QString message_type = QString::fromStdString(rosidl_generator_traits::name<MessageType>());
63-
topic_property_->setMessageType(message_type);
64-
topic_property_->setDescription(message_type + " topic to subscribe to.");
65-
}
66-
67-
/**
68-
* When overriding this method, the onInitialize() method of this superclass has to be called.
69-
* Otherwise, the ros node will not be initialized.
70-
*/
71-
void onInitialize() override
72-
{
73-
_RosTopicDisplay::onInitialize();
74-
}
75-
76-
~PointCloud2TransportDisplay() override
77-
{
78-
unsubscribe();
79-
}
80-
81-
void reset() override
82-
{
83-
Display::reset();
84-
messages_received_ = 0;
85-
}
86-
87-
void setTopic(const QString & topic, const QString & datatype) override
88-
{
89-
(void) datatype;
90-
topic_property_->setString(topic);
91-
}
92-
9358
protected:
94-
void updateTopic() override
59+
void subscribe() override
9560
{
96-
resetSubscription();
97-
}
98-
99-
virtual void subscribe()
100-
{
101-
if (!isEnabled()) {
61+
if (!this->isEnabled()) {
10262
return;
10363
}
10464

105-
if (topic_property_->isEmpty()) {
106-
setStatus(
107-
rviz_common::properties::StatusProperty::Error, "Topic",
108-
QString("Error subscribing: Empty topic name"));
65+
if (this->topic_property_->isEmpty()) {
66+
this->setStatus(rviz_common::properties::StatusProperty::Error, "Topic",
67+
QString("Error subscribing: Empty topic name"));
10968
return;
11069
}
11170

11271
try {
113-
subscription_ = std::make_shared<point_cloud_transport::SubscriberFilter>();
114-
subscription_->subscribe(
115-
*rviz_ros_node_.lock()->get_raw_node(),
116-
getPointCloud2BaseTopicFromTopic(topic_property_->getTopicStd()),
117-
getPointCloud2TransportFromTopic(topic_property_->getTopicStd()),
118-
qos_profile);
119-
subscription_start_time_ = rviz_ros_node_.lock()->get_raw_node()->now();
120-
subscription_callback_ = subscription_->registerCallback(
121-
std::bind(
122-
&PointCloud2TransportDisplay<MessageType>::incomingMessage, this, std::placeholders::_1));
123-
setStatus(rviz_common::properties::StatusProperty::Ok, "Topic", "OK");
72+
rclcpp::Node::SharedPtr node = this->rviz_ros_node_.lock()->get_raw_node();
73+
subscriber_filter_ = std::make_shared<point_cloud_transport::SubscriberFilter>();
74+
subscriber_filter_->subscribe(
75+
rclcpp::node_interfaces::NodeInterfaces<
76+
rclcpp::node_interfaces::NodeBaseInterface,
77+
rclcpp::node_interfaces::NodeParametersInterface,
78+
rclcpp::node_interfaces::NodeTopicsInterface,
79+
rclcpp::node_interfaces::NodeLoggingInterface>(*node),
80+
getPointCloud2BaseTopicFromTopic(this->topic_property_->getTopicStd()),
81+
getPointCloud2TransportFromTopic(this->topic_property_->getTopicStd()),
82+
this->qos_profile);
83+
this->subscription_start_time_ = node->now();
84+
this->tf_filter_ =
85+
std::make_shared<tf2_ros::MessageFilter<MessageType,
86+
rviz_common::transformation::FrameTransformer>>(
87+
*this->context_->getFrameManager()->getTransformer(),
88+
this->fixed_frame_.toStdString(),
89+
static_cast<uint32_t>(this->message_queue_property_->getInt()), node);
90+
this->tf_filter_->connectInput(*subscriber_filter_);
91+
this->tf_filter_->registerCallback(
92+
std::bind(&PointCloud2TransportDisplay<MessageType>::messageTaken, this,
93+
std::placeholders::_1));
94+
this->setStatus(rviz_common::properties::StatusProperty::Ok, "Topic", "OK");
12495
} catch (rclcpp::exceptions::InvalidTopicNameError & e) {
125-
setStatus(
126-
rviz_common::properties::StatusProperty::Error, "Topic",
127-
QString("Error subscribing: ") + e.what());
96+
this->setStatus(rviz_common::properties::StatusProperty::Error, "Topic",
97+
QString("Error subscribing: ") + e.what());
12898
}
12999
}
130100

131-
void transformerChangedCallback() override
132-
{
133-
resetSubscription();
134-
}
135-
136-
void resetSubscription()
137-
{
138-
unsubscribe();
139-
reset();
140-
subscribe();
141-
context_->queueRender();
142-
}
143-
144101
virtual void unsubscribe()
145102
{
146-
subscription_.reset();
147-
}
148-
149-
void onEnable() override
150-
{
151-
subscribe();
103+
rviz_common::MessageFilterDisplay<MessageType>::unsubscribe();
104+
subscriber_filter_.reset();
152105
}
153106

154-
void onDisable() override
155-
{
156-
unsubscribe();
157-
reset();
158-
}
159-
160-
/// Incoming message callback.
161-
/**
162-
* Checks if the message pointer
163-
* is valid, increments messages_received_, then calls
164-
* processMessage().
165-
*/
166-
void incomingMessage(const typename MessageType::ConstSharedPtr msg)
167-
{
168-
if (!msg) {
169-
return;
170-
}
171-
172-
++messages_received_;
173-
QString topic_str = QString::number(messages_received_) + " messages received";
174-
rviz_common::properties::StatusProperty::Level topic_status_level =
175-
rviz_common::properties::StatusProperty::Ok;
176-
// Append topic subscription frequency if we can lock rviz_ros_node_.
177-
std::shared_ptr<rviz_common::ros_integration::RosNodeAbstractionIface> node_interface =
178-
rviz_ros_node_.lock();
179-
if (node_interface != nullptr) {
180-
try {
181-
const double duration =
182-
(node_interface->get_raw_node()->now() - subscription_start_time_).seconds();
183-
const double subscription_frequency =
184-
static_cast<double>(messages_received_) / duration;
185-
topic_str += " at " + QString::number(subscription_frequency, 'f', 1) + " hz.";
186-
} catch (const std::runtime_error & e) {
187-
if (std::string(e.what()).find("can't subtract times with different time sources") !=
188-
std::string::npos)
189-
{
190-
topic_status_level = rviz_common::properties::StatusProperty::Warn;
191-
topic_str += ". ";
192-
topic_str += e.what();
193-
} else {
194-
throw;
195-
}
196-
}
197-
}
198-
setStatus(
199-
topic_status_level,
200-
"Topic",
201-
topic_str);
202-
203-
processMessage(msg);
204-
}
205-
206-
207-
/// Implement this to process the contents of a message.
208-
/**
209-
* This is called by incomingMessage().
210-
*/
211-
virtual void processMessage(typename MessageType::ConstSharedPtr msg) = 0;
212-
213-
uint32_t messages_received_;
214-
rclcpp::Time subscription_start_time_;
215-
216-
std::shared_ptr<point_cloud_transport::SubscriberFilter> subscription_;
217-
message_filters::Connection subscription_callback_;
107+
std::shared_ptr<point_cloud_transport::SubscriberFilter> subscriber_filter_;
218108
};
219109

220110
} // end namespace displays
221111
} // end namespace rviz_default_plugins
222112

223-
224113
#endif // RVIZ_DEFAULT_PLUGINS__DISPLAYS__POINTCLOUD__POINT_CLOUD_TRANSPORT_DISPLAY_HPP_

0 commit comments

Comments
 (0)