Skip to content

Commit 4da3acf

Browse files
authored
Only subscribe to /gazebo/performance_metrics when necessary (#1209)
Backport of #1202 to kinetic-level. We are currently subscribing to the /gazebo/performance_metrics topic even if there are no subscribers to the ROS topic forwarding this data. The link_states and model_states topics currently use an advertise mechanism with callbacks when a subscriber connects or disconnects, so I've used that same pattern for the performance_metrics topic. This also helps workaround the deadlock documented in #1175 and gazebosim/gazebo-classic#2902. This also adds a GAZEBO_ROS_HAS_PERFORMANCE_METRICS macro that reduces duplication of the version checking logic for performance metrics in gazebo and adds fixes some doc-string and typos in existing code Signed-off-by: Steve Peters <scpeters@openrobotics.org>
1 parent a63566b commit 4da3acf

File tree

2 files changed

+57
-14
lines changed

2 files changed

+57
-14
lines changed

gazebo_ros/include/gazebo_ros/gazebo_ros_api_plugin.h

+21-5
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@
101101

102102
#include <boost/algorithm/string.hpp>
103103

104+
#ifndef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
105+
#if (GAZEBO_MAJOR_VERSION == 11 && GAZEBO_MINOR_VERSION > 1) || \
106+
(GAZEBO_MAJOR_VERSION == 9 && GAZEBO_MINOR_VERSION > 14)
107+
#define GAZEBO_ROS_HAS_PERFORMANCE_METRICS
108+
#endif
109+
#endif // ifndef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
110+
104111
namespace gazebo
105112
{
106113

@@ -131,18 +138,26 @@ class GazeboRosApiPlugin : public SystemPlugin
131138
/// \brief advertise services
132139
void advertiseServices();
133140

134-
/// \brief
141+
/// \brief Callback for a subscriber connecting to LinkStates ros topic.
135142
void onLinkStatesConnect();
136143

137-
/// \brief
144+
/// \brief Callback for a subscriber connecting to ModelStates ros topic.
138145
void onModelStatesConnect();
139146

140-
/// \brief
147+
/// \brief Callback for a subscriber disconnecting from LinkStates ros topic.
141148
void onLinkStatesDisconnect();
142149

143-
/// \brief
150+
/// \brief Callback for a subscriber disconnecting from ModelStates ros topic.
144151
void onModelStatesDisconnect();
145152

153+
#ifdef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
154+
/// \brief Callback for a subscriber connecting to PerformanceMetrics ros topic.
155+
void onPerformanceMetricsConnect();
156+
157+
/// \brief Callback for a subscriber disconnecting from PerformanceMetrics ros topic.
158+
void onPerformanceMetricsDisconnect();
159+
#endif
160+
146161
/// \brief Function for inserting a URDF into Gazebo from ROS Service Call
147162
bool spawnURDFModel(gazebo_msgs::SpawnModel::Request &req,
148163
gazebo_msgs::SpawnModel::Response &res);
@@ -292,7 +307,7 @@ class GazeboRosApiPlugin : public SystemPlugin
292307
/// \brief Unused
293308
void onResponse(ConstResponsePtr &response);
294309

295-
#if (GAZEBO_MAJOR_VERSION == 11 && GAZEBO_MINOR_VERSION > 1) || (GAZEBO_MAJOR_VERSION == 9 && GAZEBO_MINOR_VERSION > 14)
310+
#ifdef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
296311
/// \brief Subscriber callback for performance metrics. This will be send in the ROS network
297312
void onPerformanceMetrics(const boost::shared_ptr<gazebo::msgs::PerformanceMetrics const> &msg);
298313
#endif
@@ -375,6 +390,7 @@ class GazeboRosApiPlugin : public SystemPlugin
375390
ros::Publisher pub_performance_metrics_;
376391
int pub_link_states_connection_count_;
377392
int pub_model_states_connection_count_;
393+
int pub_performance_metrics_connection_count_;
378394

379395
// ROS comm
380396
boost::shared_ptr<ros::AsyncSpinner> async_ros_spin_;

gazebo_ros/src/gazebo_ros_api_plugin.cpp

+36-9
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ GazeboRosApiPlugin::GazeboRosApiPlugin() :
3232
stop_(false),
3333
pub_link_states_connection_count_(0),
3434
pub_model_states_connection_count_(0),
35+
pub_performance_metrics_connection_count_(0),
3536
physics_reconfigure_initialized_(false),
3637
pub_clock_frequency_(0),
3738
world_created_(false)
@@ -187,13 +188,10 @@ void GazeboRosApiPlugin::loadGazeboRosApiPlugin(std::string world_name)
187188
light_modify_pub_ = gazebonode_->Advertise<gazebo::msgs::Light>("~/light/modify");
188189
request_pub_ = gazebonode_->Advertise<gazebo::msgs::Request>("~/request");
189190
response_sub_ = gazebonode_->Subscribe("~/response",&GazeboRosApiPlugin::onResponse, this);
190-
#if (GAZEBO_MAJOR_VERSION == 11 && GAZEBO_MINOR_VERSION > 1) || (GAZEBO_MAJOR_VERSION == 9 && GAZEBO_MINOR_VERSION > 14)
191-
performance_metric_sub_ = gazebonode_->Subscribe("/gazebo/performance_metrics",
192-
&GazeboRosApiPlugin::onPerformanceMetrics, this);
193-
#endif
194191
// reset topic connection counts
195192
pub_link_states_connection_count_ = 0;
196193
pub_model_states_connection_count_ = 0;
194+
pub_performance_metrics_connection_count_ = 0;
197195

198196
/// \brief advertise all services
199197
advertiseServices();
@@ -208,7 +206,7 @@ void GazeboRosApiPlugin::onResponse(ConstResponsePtr &response)
208206
{
209207

210208
}
211-
#if (GAZEBO_MAJOR_VERSION == 11 && GAZEBO_MINOR_VERSION > 1) || (GAZEBO_MAJOR_VERSION == 9 && GAZEBO_MINOR_VERSION > 14)
209+
#ifdef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
212210
void GazeboRosApiPlugin::onPerformanceMetrics(const boost::shared_ptr<gazebo::msgs::PerformanceMetrics const> &msg)
213211
{
214212
gazebo_msgs::PerformanceMetrics msg_ros;
@@ -385,9 +383,15 @@ void GazeboRosApiPlugin::advertiseServices()
385383
ros::VoidPtr(), &gazebo_queue_);
386384
pub_model_states_ = nh_->advertise(pub_model_states_ao);
387385

388-
#if (GAZEBO_MAJOR_VERSION == 11 && GAZEBO_MINOR_VERSION > 1) || (GAZEBO_MAJOR_VERSION == 9 && GAZEBO_MINOR_VERSION > 14)
386+
#ifdef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
389387
// publish performance metrics
390-
pub_performance_metrics_ = nh_->advertise<gazebo_msgs::PerformanceMetrics>("performance_metrics", 10);
388+
ros::AdvertiseOptions pub_performance_metrics_ao =
389+
ros::AdvertiseOptions::create<gazebo_msgs::PerformanceMetrics>(
390+
"performance_metrics",10,
391+
boost::bind(&GazeboRosApiPlugin::onPerformanceMetricsConnect,this),
392+
boost::bind(&GazeboRosApiPlugin::onPerformanceMetricsDisconnect,this),
393+
ros::VoidPtr(), &gazebo_queue_);
394+
pub_performance_metrics_ = nh_->advertise(pub_performance_metrics_ao);
391395
#endif
392396

393397
// Advertise more services on the custom queue
@@ -561,14 +565,37 @@ void GazeboRosApiPlugin::onModelStatesConnect()
561565
pub_model_states_event_ = gazebo::event::Events::ConnectWorldUpdateBegin(boost::bind(&GazeboRosApiPlugin::publishModelStates,this));
562566
}
563567

568+
#ifdef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
569+
void GazeboRosApiPlugin::onPerformanceMetricsConnect()
570+
{
571+
pub_performance_metrics_connection_count_++;
572+
if (pub_performance_metrics_connection_count_ == 1) // connect on first subscriber
573+
{
574+
performance_metric_sub_ = gazebonode_->Subscribe("/gazebo/performance_metrics",
575+
&GazeboRosApiPlugin::onPerformanceMetrics, this);
576+
}
577+
}
578+
579+
void GazeboRosApiPlugin::onPerformanceMetricsDisconnect()
580+
{
581+
pub_performance_metrics_connection_count_--;
582+
if (pub_performance_metrics_connection_count_ <= 0) // disconnect with no subscribers
583+
{
584+
performance_metric_sub_.reset();
585+
if (pub_performance_metrics_connection_count_ < 0) // should not be possible
586+
ROS_ERROR_NAMED("api_plugin", "One too many disconnect from pub_performance_metrics_ in gazebo_ros.cpp? something weird");
587+
}
588+
}
589+
#endif
590+
564591
void GazeboRosApiPlugin::onLinkStatesDisconnect()
565592
{
566593
pub_link_states_connection_count_--;
567594
if (pub_link_states_connection_count_ <= 0) // disconnect with no subscribers
568595
{
569596
pub_link_states_event_.reset();
570597
if (pub_link_states_connection_count_ < 0) // should not be possible
571-
ROS_ERROR_NAMED("api_plugin", "One too mandy disconnect from pub_link_states_ in gazebo_ros.cpp? something weird");
598+
ROS_ERROR_NAMED("api_plugin", "One too many disconnect from pub_link_states_ in gazebo_ros.cpp? something weird");
572599
}
573600
}
574601

@@ -579,7 +606,7 @@ void GazeboRosApiPlugin::onModelStatesDisconnect()
579606
{
580607
pub_model_states_event_.reset();
581608
if (pub_model_states_connection_count_ < 0) // should not be possible
582-
ROS_ERROR_NAMED("api_plugin", "One too mandy disconnect from pub_model_states_ in gazebo_ros.cpp? something weird");
609+
ROS_ERROR_NAMED("api_plugin", "One too many disconnect from pub_model_states_ in gazebo_ros.cpp? something weird");
583610
}
584611
}
585612

0 commit comments

Comments
 (0)