Skip to content

Commit c5a6909

Browse files
committed
Subscribe to gazebo topic on ROS topic connection
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 ros-simulation#1175 and gazebosim/gazebo-classic#2902. Signed-off-by: Steve Peters <scpeters@openrobotics.org>
1 parent 577a001 commit c5a6909

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

gazebo_ros/include/gazebo_ros/gazebo_ros_api_plugin.h

+9
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ class GazeboRosApiPlugin : public SystemPlugin
150150
/// \brief Callback for a subscriber disconnecting from ModelStates ros topic.
151151
void onModelStatesDisconnect();
152152

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+
153161
/// \brief Function for inserting a URDF into Gazebo from ROS Service Call
154162
bool spawnURDFModel(gazebo_msgs::SpawnModel::Request &req,
155163
gazebo_msgs::SpawnModel::Response &res);
@@ -382,6 +390,7 @@ class GazeboRosApiPlugin : public SystemPlugin
382390
ros::Publisher pub_performance_metrics_;
383391
int pub_link_states_connection_count_;
384392
int pub_model_states_connection_count_;
393+
int pub_performance_metrics_connection_count_;
385394

386395
// ROS comm
387396
boost::shared_ptr<ros::AsyncSpinner> async_ros_spin_;

gazebo_ros/src/gazebo_ros_api_plugin.cpp

+32-5
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-
#ifdef GAZEBO_ROS_HAS_PERFORMANCE_METRICS
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();
@@ -387,7 +385,13 @@ void GazeboRosApiPlugin::advertiseServices()
387385

388386
#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,6 +565,29 @@ 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_--;

0 commit comments

Comments
 (0)