37 #ifndef REALTIME_TOOLS__REALTIME_PUBLISHER_HPP_
38 #define REALTIME_TOOLS__REALTIME_PUBLISHER_HPP_
42 #include <condition_variable>
48 #include "rclcpp/publisher.hpp"
52 template <
class MessageT>
58 using PublisherSharedPtr =
typename rclcpp::Publisher<MessageT>::SharedPtr;
60 using PublishedType =
typename rclcpp::TypeAdapter<MessageT>::custom_type;
61 using ROSMessageType =
typename rclcpp::TypeAdapter<MessageT>::ros_message_type;
73 : publisher_(publisher), is_running_(false), keep_running_(true), turn_(State::LOOP_NOT_STARTED)
75 thread_ = std::thread(&RealtimePublisher::publishingLoop,
this);
79 "Use constructor with rclcpp::Publisher<T>::SharedPtr instead - this class does not make sense "
80 "without a real publisher")]]
82 : is_running_(false), keep_running_(false), turn_(State::LOOP_NOT_STARTED)
90 while (is_running()) {
91 std::this_thread::sleep_for(std::chrono::microseconds(100));
93 if (thread_.joinable()) {
101 keep_running_ =
false;
103 updated_cond_.notify_one();
115 if (msg_mutex_.try_lock()) {
116 if (turn_ == State::REALTIME) {
152 turn_ = State::NON_REALTIME;
168 while (!msg_mutex_.try_lock()) {
169 std::this_thread::sleep_for(std::chrono::microseconds(200));
181 updated_cond_.notify_one();
185 std::thread & get_thread() {
return thread_; }
187 const std::thread & get_thread()
const {
return thread_; }
194 bool is_running()
const {
return is_running_; }
196 void publishingLoop()
199 turn_ = State::REALTIME;
201 while (keep_running_) {
207 std::unique_lock<std::mutex> lock_(msg_mutex_);
212 while (turn_ != State::NON_REALTIME && keep_running_) {
214 updated_cond_.wait(lock_);
217 std::this_thread::sleep_for(std::chrono::microseconds(500));
222 turn_ = State::REALTIME;
228 publisher_->publish(outgoing);
234 PublisherSharedPtr publisher_;
235 std::atomic<bool> is_running_;
236 std::atomic<bool> keep_running_;
240 std::mutex msg_mutex_;
243 std::condition_variable updated_cond_;
246 enum class State : int { REALTIME, NON_REALTIME, LOOP_NOT_STARTED };
247 std::atomic<State> turn_;
250 template <
class MessageT>
251 using RealtimePublisherSharedPtr = std::shared_ptr<RealtimePublisher<MessageT>>;