cnoid_ros_utils
ClockPublisherItem.cpp
Go to the documentation of this file.
1 /* Author: Masaki Murooka */
2 
3 #include <cnoid/BodyItem>
4 #include <cnoid/ItemManager>
5 #include <cnoid/MessageView>
6 #include <cnoid/PutPropertyFunction>
7 #include <cnoid/RootItem>
8 
9 #include "ClockPublisherItem.h"
10 
11 using namespace CnoidRosUtils;
12 
13 void ClockPublisherItem::initialize(cnoid::ExtensionManager * ext)
14 {
15  int argc = 0;
16  char ** argv;
17  if(!rclcpp::ok())
18  {
19  rclcpp::init(argc, argv);
20  }
21 
22  if(!initialized_)
23  {
24  ext->itemManager().registerClass<ClockPublisherItem>("CnoidRosUtils::ClockPublisherItem");
25  ext->itemManager().addCreationPanel<ClockPublisherItem>();
26  initialized_ = true;
27  }
28 }
29 
31 {
32  cnoid::RootItem::instance()->sigSubTreeChanged().connect(std::bind(&ClockPublisherItem::setup, this));
33 }
34 
36 {
37  cnoid::RootItem::instance()->sigSubTreeChanged().connect(std::bind(&ClockPublisherItem::setup, this));
38  hooked_sims_.clear();
40  sim_cnt_ = 0;
41 }
42 
44 {
45  stop();
46 }
47 
48 cnoid::Item * ClockPublisherItem::doDuplicate() const
49 {
50  return new ClockPublisherItem(*this);
51 }
52 
53 void ClockPublisherItem::doPutProperties(cnoid::PutPropertyFunction & putProperty)
54 {
55  cnoid::Item::doPutProperties(putProperty);
56  putProperty("Clock topic name", clock_topic_name_, cnoid::changeProperty(clock_topic_name_));
57  putProperty("Publish rate", pub_rate_,
58  [&](const double & pub_rate)
59  {
60  pub_rate_ = std::min(std::max(pub_rate, 1e-1), 1e3);
61  if(sim_)
62  {
64  }
65  return true;
66  });
67  putProperty("Set use_sim_time", use_sim_time_, cnoid::changeProperty(use_sim_time_));
68 }
69 
70 bool ClockPublisherItem::store(cnoid::Archive & archive)
71 {
72  archive.write("Clock topic name", clock_topic_name_);
73  archive.write("Publish rate", pub_rate_);
74  archive.write("Set use_sim_time", use_sim_time_);
75 
76  return true;
77 }
78 
79 bool ClockPublisherItem::restore(const cnoid::Archive & archive)
80 {
81  archive.read("Clock topic name", clock_topic_name_);
82  archive.read("Publish rate", pub_rate_);
83  archive.read("Set use_sim_time", use_sim_time_);
84 
85  return true;
86 }
87 
89 {
90  // Get WorldItem
91  world_ = this->findOwnerItem<cnoid::WorldItem>();
92  if(!world_)
93  {
94  // cnoid::MessageView::instance()->putln("[ClockPublisherItem] WorldItem not found", cnoid::MessageView::ERROR);
95  return;
96  }
97 
98  // Set hook functions for simulation start and stop
99  for(Item * child = world_->childItem(); child; child = child->nextItem())
100  {
101  cnoid::SimulatorItemPtr sim = dynamic_cast<cnoid::SimulatorItem *>(child);
102  if(sim && !sim->isRunning() && !hooked_sims_.count(sim->name()))
103  {
104  sim->sigSimulationStarted().connect(std::bind(&ClockPublisherItem::start, this));
105  sim->sigSimulationFinished().connect(std::bind(&ClockPublisherItem::stop, this));
106  hooked_sims_.insert(sim->name());
107  }
108  }
109 }
110 
112 {
113  // Get SimulatorItem
114  sim_ = cnoid::SimulatorItem::findActiveSimulatorItemFor(this);
115  if(!sim_)
116  {
117  cnoid::MessageView::instance()->putln("[ClockPublisherItem] SimulatorItem not found", cnoid::MessageView::ERROR);
118  return false;
119  }
120 
121  // Setup ROS
122  nh_ = rclcpp::Node::make_shared("CnoidPlugin::ClockPublisher");
123 
124  if(clock_topic_name_.empty())
125  {
126  clock_topic_name_ = "/clock";
127  }
128  clock_pub_ = nh_->create_publisher<rosgraph_msgs::msg::Clock>(clock_topic_name_, 1);
129  pub_skip_ = getPubSkip();
130 
131  nh_->declare_parameter<bool>("use_sim_time", use_sim_time_);
132  nh_->set_parameter(rclcpp::Parameter("use_sim_time", use_sim_time_));
133 
134  // Add postDynamicsFunction
135  post_dynamics_func_id_ = sim_->addPostDynamicsFunction(std::bind(&ClockPublisherItem::onPostDynamics, this));
136 
137  return true;
138 }
139 
141 {
142  // Remove postDynamicsFunction
143  if(post_dynamics_func_id_ != -1)
144  {
145  sim_->removePostDynamicsFunction(post_dynamics_func_id_);
147  }
148 }
149 
151 {
152  sim_cnt_++;
153  if(sim_cnt_ % pub_skip_ != 0)
154  {
155  return;
156  }
157 
158  // Publish a message
159  rosgraph_msgs::msg::Clock msg;
160  msg.clock = rclcpp::Time(static_cast<int64_t>(sim_->currentTime() * 1e9));
161 
162  clock_pub_->publish(msg);
163 }
164 
166 {
167  return std::max(static_cast<int>(1.0 / (pub_rate_ * sim_->worldTimeStep())), 1);
168 }
Plugin item to publish clock topic.
virtual bool store(cnoid::Archive &archive) override
virtual bool restore(const cnoid::Archive &archive) override
virtual void doPutProperties(cnoid::PutPropertyFunction &putProperty) override
virtual cnoid::Item * doDuplicate() const override
std::set< std::string > hooked_sims_
rclcpp::Publisher< rosgraph_msgs::msg::Clock >::SharedPtr clock_pub_
static void initialize(cnoid::ExtensionManager *ext)