Skip to content
Snippets Groups Projects
ros_init.cpp 2.45 KiB
Newer Older
#include <stdexcept>
Thomas Moulard's avatar
Thomas Moulard committed
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>

#include "dynamic_graph_bridge/ros_init.hh"
Thomas Moulard's avatar
Thomas Moulard committed

Olivier Stasse's avatar
Olivier Stasse committed
namespace dynamicgraph {
struct GlobalRos {
  ~GlobalRos() {
    if (spinner) spinner->stop();
    if (nodeHandle) nodeHandle->shutdown();
  }
Thomas Moulard's avatar
Thomas Moulard committed

Olivier Stasse's avatar
Olivier Stasse committed
  boost::shared_ptr<ros::NodeHandle> nodeHandle;
  boost::shared_ptr<ros::AsyncSpinner> spinner;
  boost::shared_ptr<ros::MultiThreadedSpinner> mtSpinner;
};
GlobalRos ros;
Thomas Moulard's avatar
Thomas Moulard committed

Guilhem Saurel's avatar
Guilhem Saurel committed
ros::NodeHandle& rosInit(bool createAsyncSpinner, bool createMultiThreadedSpinner) {
Olivier Stasse's avatar
Olivier Stasse committed
  if (!ros.nodeHandle) {
    int argc = 1;
    char* arg0 = strdup("dynamic_graph_bridge");
    char* argv[] = {arg0, 0};
    ros::init(argc, argv, "dynamic_graph_bridge");
    free(arg0);
Olivier Stasse's avatar
Olivier Stasse committed
    ros.nodeHandle = boost::make_shared<ros::NodeHandle>("");
Olivier Stasse's avatar
Olivier Stasse committed
  if (!ros.spinner && createAsyncSpinner) {
    ros.spinner = boost::make_shared<ros::AsyncSpinner>(4);
Olivier Stasse's avatar
Olivier Stasse committed
    // Change the thread's scheduler from real-time to normal and reduce its
    // priority
    int oldThreadPolicy, newThreadPolicy;
    struct sched_param oldThreadParam, newThreadParam;
Guilhem Saurel's avatar
Guilhem Saurel committed
    if (pthread_getschedparam(pthread_self(), &oldThreadPolicy, &oldThreadParam) == 0) {
Olivier Stasse's avatar
Olivier Stasse committed
      newThreadPolicy = SCHED_OTHER;
      newThreadParam = oldThreadParam;
Guilhem Saurel's avatar
Guilhem Saurel committed
      newThreadParam.sched_priority -= 5;  // Arbitrary number, TODO: choose via param/file?
      if (newThreadParam.sched_priority < sched_get_priority_min(newThreadPolicy))
Olivier Stasse's avatar
Olivier Stasse committed
        newThreadParam.sched_priority = sched_get_priority_min(newThreadPolicy);

      pthread_setschedparam(pthread_self(), newThreadPolicy, &newThreadParam);
    }

    // AsyncSpinners are created with the reduced priority
    ros.spinner->start();
Olivier Stasse's avatar
Olivier Stasse committed
    // Switch the priority of the parent thread (this thread) back to real-time.
    pthread_setschedparam(pthread_self(), oldThreadPolicy, &oldThreadParam);
  } else {
    if (!ros.mtSpinner && createMultiThreadedSpinner) {
      // Seems not to be used.
      // If we need to reduce its threads priority, it needs to be done before
      // calling the MultiThreadedSpinner::spin() method
      ros.mtSpinner = boost::make_shared<ros::MultiThreadedSpinner>(4);
    }
Olivier Stasse's avatar
Olivier Stasse committed
  return *ros.nodeHandle;
}

ros::AsyncSpinner& spinner() {
  if (!ros.spinner) throw std::runtime_error("spinner has not been created");
  return *ros.spinner;
}

ros::MultiThreadedSpinner& mtSpinner() {
  if (!ros.mtSpinner) throw std::runtime_error("spinner has not been created");
  return *ros.mtSpinner;
}
Olivier Stasse's avatar
Olivier Stasse committed
}  // end of namespace dynamicgraph.