ROS实时控制:realtime_tools/realtime_publisher

来源:http://wiki.ros.org/realtime_tools
在进行机械臂的实时控制时,为了尽可能的保证话题的实时性,我们使用官方的realtime_tools。
在这里插入图片描述
下面看看官方说明:
此包包含一组可以在硬实时线程中使用的工具,而不会破坏实时行为。 这些工具目前仅提供
realtime publisher,这使得它可以从实时线程向ROS主题发布消息。
realtime_tools :: RealtimePublisher允许编写C ++实时控制器的用户从硬实时循环中发布ROS主题上的消息。 普通的ROS发布者不是实时可靠的,不应该在实时控制器的更新循环中使用。 RealtimePublisher是ROS发布者的包装器; 包装器创建一个额外的非实时线程,用于发布ROS主题的消息。 下面的示例显示了实时发布者在实时控制器的init()和update()方法中的典型用法:

#include <realtime_tools/realtime_publisher.h>

bool MyController::init(pr2_mechanism_model::RobotState *robot,
                        ros::NodeHandle &n)
{
  ...

  realtime_pub = new 
    realtime_tools::RealtimePublisher<mgs_type>(n, "topic", 4);
  return true;
}


void MyController::update()
{
  if (realtime_pub->trylock()){
    realtime_pub->msg_.a_field = "hallo";
    realtime_pub->msg_.header.stamp = ros::Time::now();
    realtime_pub->unlockAndPublish();
  }
  ...
}

下面看看class RealtimePublisher的定义

/*
 * Copyright (c) 2008, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Publishing ROS messages is difficult, as the publish function is
 * not realtime safe.  This class provides the proper locking so that
 * you can call publish in realtime and a separate (non-realtime)
 * thread will ensure that the message gets published over ROS.
 *
 * Author: Stuart Glaser
 */
#ifndef REALTIME_TOOLS__REALTIME_PUBLISHER_H_
#define REALTIME_TOOLS__REALTIME_PUBLISHER_H_

#include <string>
#include <ros/node_handle.h>
#include <boost/utility.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/condition.hpp>
#include <chrono>
#include <thread>

namespace realtime_tools {

template <class Msg>
class RealtimePublisher : boost::noncopyable
{

public:
  /// The msg_ variable contains the data that will get published on the ROS topic.
  Msg msg_;
  
  /**  \brief Constructor for the realtime publisher
   *
   * \param node the nodehandle that specifies the namespace (or prefix) that is used to advertise the ROS topic
   * \param topic the topic name to advertise
   * \param queue_size the size of the outgoing ROS buffer
   * \param latched . optional argument (defaults to false) to specify is publisher is latched or not
   */
  RealtimePublisher(const ros::NodeHandle &node, const std::string &topic, int queue_size, bool latched=false)
    : topic_(topic), node_(node), is_running_(false), keep_running_(false), turn_(REALTIME)
  {
    construct(queue_size, latched);
  }

  RealtimePublisher()
    : is_running_(false), keep_running_(false), turn_(REALTIME)
  {
  }

  /// Destructor
  ~RealtimePublisher()
  {
    stop();
    while (is_running())
    {
      std::this_thread::sleep_for(std::chrono::microseconds(100));
    }

    publisher_.shutdown();
  }

  void init(const ros::NodeHandle &node, const std::string &topic, int queue_size, bool latched=false)
  {
    topic_ = topic;
    node_ = node;
    construct(queue_size, latched);
  }

  /// Stop the realtime publisher from sending out more ROS messages
  void stop()
  {
    keep_running_ = false;
#ifdef NON_POLLING
    updated_cond_.notify_one();  // So the publishing loop can exit
#endif
  }

  /**  \brief Try to get the data lock from realtime
   *
   * To publish data from the realtime loop, you need to run trylock to
   * attempt to get unique access to the msg_ variable. Trylock returns
   * true if the lock was aquired, and false if it failed to get the lock.
   */
  bool trylock()
  {
    if (msg_mutex_.try_lock())
    {
      if (turn_ == REALTIME)
      {
        return true;
      }
      else
      {
        msg_mutex_.unlock();
        return false;
      }
    }
    else
    {
      return false;
    }
  }

  /**  \brief Unlock the msg_ variable
   *
   * After a successful trylock and after the data is written to the mgs_
   * variable, the lock has to be released for the message to get
   * published on the specified topic.
   */
  void unlockAndPublish()
  {
    turn_ = NON_REALTIME;
    msg_mutex_.unlock();
#ifdef NON_POLLING
    updated_cond_.notify_one();
#endif
  }

  /**  \brief Get the data lock form non-realtime
   *
   * To publish data from the realtime loop, you need to run trylock to
   * attempt to get unique access to the msg_ variable. Trylock returns
   * true if the lock was aquired, and false if it failed to get the lock.
   */
  void lock()
  {
#ifdef NON_POLLING
    msg_mutex_.lock();
#else
    // never actually block on the lock
    while (!msg_mutex_.try_lock())
    {
      std::this_thread::sleep_for(std::chrono::microseconds(200));
    }
#endif
  }

  /**  \brief Unlocks the data without publishing anything
   *
   */
  void unlock()
  {
    msg_mutex_.unlock();
  }

private:
  void construct(int queue_size, bool latched=false)
  {
    publisher_ = node_.advertise<Msg>(topic_, queue_size, latched);
    keep_running_ = true;
    thread_ = boost::thread(&RealtimePublisher::publishingLoop, this);
  }


  bool is_running() const { return is_running_; }

  void publishingLoop()
  {
    is_running_ = true;
    turn_ = REALTIME;

    while (keep_running_)
    {
      Msg outgoing;

      // Locks msg_ and copies it
      lock();
      while (turn_ != NON_REALTIME && keep_running_)
      {
#ifdef NON_POLLING
        updated_cond_.wait(lock);
#else
        unlock();
        std::this_thread::sleep_for(std::chrono::microseconds(500));
        lock();
#endif
      }
      outgoing = msg_;
      turn_ = REALTIME;

      unlock();

      // Sends the outgoing message
      if (keep_running_)
        publisher_.publish(outgoing);
    }
    is_running_ = false;
  }

  std::string topic_;
  ros::NodeHandle node_;
  ros::Publisher publisher_;
  volatile bool is_running_;
  volatile bool keep_running_;

  boost::thread thread_;

  boost::mutex msg_mutex_;  // Protects msg_

#ifdef NON_POLLING
  boost::condition_variable updated_cond_;
#endif

  enum {REALTIME, NON_REALTIME};
  int turn_;  // Who's turn is it to use msg_?
};

#include <memory>
template <class Msg>
using RealtimePublisherSharedPtr = std::shared_ptr<RealtimePublisher<Msg> >;

}

#endif
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fatal error: pcl_ros/transforms.h: No such file or directory是一个编译错误,意味着编译器无法找到pcl_ros/transforms.h文件或目录。为了解决这个问题,您可以按照以下步骤进行操作: 1. 首先,请确保您已经安装了正确的PCL软件包和ROS软件包。您可以使用命令`sudo apt-get install ros-<your_ros_version>-pcl-ros`来安装pcl_ros软件包。 2. 确认您的源代码中是否正确引用了pcl_ros/transforms.h文件。您可以使用`#include <pcl_ros/transforms.h>`来引用该文件。 3. 检查您的cmakelists.txt文件,确保正确设置了依赖项和包含目录。根据引用中提供的信息,您需要在cmakelists.txt中添加以下内容: - 在第5行添加`find_package(PCL REQUIRED)`以找到PCL包。 - 在第14行的包含目录中添加`${PCL_INCLUDE_DIRS}`以包含PCL文件。 - 在第42行中使用`target_link_libraries`链接到PCL库,例如`target_link_libraries(your_target_name ${PCL_LIBRARIES})`。 4. 如果以上步骤都已完成,并且仍然出现相同的错误,请确保您的文件路径和命名正确,并且文件实际存在于指定的目录中。 通过执行上述步骤,您应该能够解决fatal error: pcl_ros/transforms.h: No such file or directory的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SLAM2添加稠密重建模块,ROS编译报错:fatal error: pcl/common/transforms.h: No such file or directory](https://blog.csdn.net/weixin_44401286/article/details/102752911)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [fatal error: boostdesc_bgm.i: No such file or directory补充文件](https://download.csdn.net/download/qq_26631621/44054087)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [mpl_ros](https://blog.csdn.net/asd22222984565/article/details/127844544)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值