Skip to content
Snippets Groups Projects
ros_init.cpp 2.63 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

namespace dynamicgraph
{
  struct GlobalRos
  {
    ~GlobalRos ()
    {
      if (spinner)
	spinner->stop ();
      if (nodeHandle)
	nodeHandle->shutdown ();
    }

    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

  ros::NodeHandle& rosInit (bool createAsyncSpinner, bool createMultiThreadedSpinner)
Thomas Moulard's avatar
Thomas Moulard committed
  {
    if (!ros.nodeHandle)
Thomas Moulard's avatar
Thomas Moulard committed
      {
	int argc = 1;
	char* arg0 = strdup("dynamic_graph_bridge");
	char* argv[] = {arg0, 0};
	ros::init(argc, argv, "dynamic_graph_bridge");
	free (arg0);

	ros.nodeHandle = boost::make_shared<ros::NodeHandle> ("");
      }
    if (!ros.spinner && createAsyncSpinner)
      {
	ros.spinner = boost::make_shared<ros::AsyncSpinner> (4);

        // Change the thread's scheduler from real-time to normal and reduce its priority
        int oldThreadPolicy, newThreadPolicy;
        struct sched_param oldThreadParam, newThreadParam;
        if (pthread_getschedparam (pthread_self(), &oldThreadPolicy, &oldThreadParam) == 0)
        {
          newThreadPolicy = SCHED_OTHER;
          newThreadParam = oldThreadParam;
          newThreadParam.sched_priority -= 5; // Arbitrary number, TODO: choose via param/file?
          if (newThreadParam.sched_priority < sched_get_priority_min (newThreadPolicy))
            newThreadParam.sched_priority = sched_get_priority_min (newThreadPolicy);
           
          pthread_setschedparam (pthread_self(), newThreadPolicy, &newThreadParam);
        } 
        
        // AsyncSpinners are created with the reduced priority
	ros.spinner->start ();
        
        // Switch the priority of the parent thread (this thread) back to real-time.
        pthread_setschedparam (pthread_self(), oldThreadPolicy, &oldThreadParam);
Thomas Moulard's avatar
Thomas Moulard committed
      }
    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);
	  }
      }
    return *ros.nodeHandle;
  }

  ros::AsyncSpinner& spinner ()
  {
    if (!ros.spinner)
      throw std::runtime_error ("spinner has not been created");
    return *ros.spinner;
Thomas Moulard's avatar
Thomas Moulard committed
  }

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

Thomas Moulard's avatar
Thomas Moulard committed
} // end of namespace dynamicgraph.