@@ -35,7 +35,7 @@ PoseBroadcaster::state_interface_configuration() const {
3535
3636controller_interface::return_type
3737PoseBroadcaster::update (const rclcpp::Time &time,
38- const rclcpp::Duration & /* period*/ ) {
38+ const rclcpp::Duration &period) {
3939
4040 size_t num_joints = params_.joints .size ();
4141 Eigen::VectorXd q_pin = Eigen::VectorXd::Zero (model_.nq );
@@ -63,28 +63,28 @@ PoseBroadcaster::update(const rclcpp::Time &time,
6363 Eigen::Quaterniond (current_pose.rotation ());
6464
6565 // Decide whether to publish the pose or not
66- bool should_publish = true ;
67- if (params_.publish_frequency > 0.0 ) {
68- auto time_since_last = time - last_publish_time_;
69- auto min_interval = rclcpp::Duration::from_seconds (1.0 / params_.publish_frequency );
70- should_publish = time_since_last >= min_interval;
71- }
72-
73- if (should_publish && realtime_pose_publisher_ && realtime_pose_publisher_->trylock ())
66+ publish_elapsed_ = publish_elapsed_ + period;
67+ bool should_publish = (publish_elapsed_ >= publish_interval_) ||
68+ (publish_interval_.nanoseconds () == 0 );
69+ if (should_publish && realtime_pose_publisher_)
7470 {
75- auto & pose_msg = realtime_pose_publisher_->msg_ ;
76-
77- pose_msg.header .stamp = time;
78- pose_msg.header .frame_id = params_.base_frame ;
79- pose_msg.pose .position .x = current_pose.translation ()[0 ];
80- pose_msg.pose .position .y = current_pose.translation ()[1 ];
81- pose_msg.pose .position .z = current_pose.translation ()[2 ];
82- pose_msg.pose .orientation .x = current_quaternion.x ();
83- pose_msg.pose .orientation .y = current_quaternion.y ();
84- pose_msg.pose .orientation .z = current_quaternion.z ();
85- pose_msg.pose .orientation .w = current_quaternion.w ();
86- realtime_pose_publisher_->unlockAndPublish ();
87- last_publish_time_ = time;
71+ if (realtime_pose_publisher_->trylock ()) {
72+ auto & pose_msg = realtime_pose_publisher_->msg_ ;
73+ pose_msg.header .stamp = time;
74+ pose_msg.header .frame_id = params_.base_frame ;
75+ pose_msg.pose .position .x = current_pose.translation ()[0 ];
76+ pose_msg.pose .position .y = current_pose.translation ()[1 ];
77+ pose_msg.pose .position .z = current_pose.translation ()[2 ];
78+ pose_msg.pose .orientation .x = current_quaternion.x ();
79+ pose_msg.pose .orientation .y = current_quaternion.y ();
80+ pose_msg.pose .orientation .z = current_quaternion.z ();
81+ pose_msg.pose .orientation .w = current_quaternion.w ();
82+ realtime_pose_publisher_->unlockAndPublish ();
83+
84+ publish_elapsed_ = publish_elapsed_ - publish_interval_;
85+ // clamp to publish only 1 time even if missed multiple intervals
86+ publish_elapsed_ = std::min (publish_elapsed_, publish_interval_);
87+ }
8888 }
8989
9090 return controller_interface::return_type::OK ;
@@ -168,12 +168,19 @@ CallbackReturn PoseBroadcaster::on_configure(
168168 std::make_shared<realtime_tools::RealtimePublisher<geometry_msgs::msg::PoseStamped>>(
169169 pose_publisher_);
170170
171- last_publish_time_ = this ->get_node ()->now ();
171+ if (params_.publish_frequency > 0.0 ) {
172+ publish_interval_ = rclcpp::Duration::from_seconds (1.0 / params_.publish_frequency );
173+ } else {
174+ publish_interval_ = rclcpp::Duration (0 , 0 ); // publish every cycle
175+ }
176+
172177 return CallbackReturn::SUCCESS ;
173178}
174179
175180CallbackReturn PoseBroadcaster::on_activate (
176181 const rclcpp_lifecycle::State & /* previous_state*/ ) {
182+ // reset publish time accumulation
183+ publish_elapsed_ = rclcpp::Duration (0 , 0 );
177184 return CallbackReturn::SUCCESS ;
178185}
179186
0 commit comments