GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/catkin/dg_control/dynamic_graph_manager/src/ros_init.cpp Lines: 39 40 97.5 %
Date: 2020-04-15 11:50:02 Branches: 25 38 65.8 %

Line Branch Exec Source
1
/**
2
 * @file ros_init.cpp
3
 * @author Maximilien Naveau (maximilien.naveau@gmail.com)
4
 * @license License BSD-3-Clause
5
 * @copyright Copyright (c) 2019, New York University and Max Planck Gesellschaft.
6
 * @date 2019-05-22
7
 */
8
9
#include <dynamic_graph_manager/ros_init.hh>
10
11
namespace dynamic_graph
12
{
13
  /**
14
   * @brief GLOBAL_ROS_VAR is global variable that acts as a singleton on the
15
   * ROS node handle and the spinner.
16
   *
17
   * The use of the std::unique_ptr allows to delete the object and re-create
18
   * at will. It is usefull to reset the ros environment specifically for
19
   * unittesting.
20
   *
21
   * If the node handle does not exist we call the global method ros::init.
22
   * This method has for purpose to initialize the ROS environment. The
23
   * creation of ROS object is permitted only after the call of this function.
24
   * After ros::init being called we create the node hanlde which allows in
25
   * turn to advertize the ROS services, or create topics (data pipe).
26
   *
27
   */
28
3
  static std::map<std::string, std::unique_ptr<GlobalRos> > GLOBAL_ROS_VAR;
29
30
218
  ros::NodeHandle& ros_init (std::string node_name)
31
  {
32
218
    if(!ros::isInitialized())
33
    {
34
      /** call ros::init */
35
3
      int argc = 1;
36
3
      char* arg0 = strdup(node_name.c_str());
37
3
      char* argv[] = {arg0, nullptr};
38
3
      ros::init(argc, argv, node_name);
39
3
      free (arg0);
40
    }
41

218
    if (!ros_exist(node_name))
42
    {
43
182
      GLOBAL_ROS_VAR[node_name].reset(new GlobalRos());
44
    }
45
218
    if (GLOBAL_ROS_VAR[node_name]->node_handle_ == nullptr)
46
    {
47
      /** ros::NodeHandle instanciation */
48
182
      GLOBAL_ROS_VAR[node_name]->node_handle_ =
49
364
          boost::make_shared<ros::NodeHandle>(node_name);
50
    }
51
    /**
52
     * If spinner is not created we create it. Here we can safely assume that
53
     * ros::init was called before.
54
     */
55
218
    if (GLOBAL_ROS_VAR[node_name]->async_spinner_ == nullptr)
56
    {
57
      /** create the spinner */
58
182
      GLOBAL_ROS_VAR[node_name]->async_spinner_ =
59
364
          boost::make_shared<ros::AsyncSpinner> (4);
60
      /** run the spinner in a different thread */
61
182
      GLOBAL_ROS_VAR[node_name]->async_spinner_->start ();
62
    }
63
    /** Return a reference to the node handle so any function can use it */
64
218
    return *GLOBAL_ROS_VAR[node_name]->node_handle_;
65
  }
66
67
1
  ros::AsyncSpinner& ros_spinner (std::string node_name)
68
  {
69

1
    if (!ros_exist(node_name))
70
    {
71
1
      dynamic_graph::ros_init(node_name);
72
    }
73
1
    assert(GLOBAL_ROS_VAR[node_name]->async_spinner_ != nullptr &&
74
1
        "The spinner must have been created by now.");
75
1
    return *GLOBAL_ROS_VAR[node_name]->async_spinner_;
76
  }
77
78
215
  void ros_shutdown (std::string node_name)
79
  {
80
215
    GLOBAL_ROS_VAR.erase(node_name);
81
215
  }
82
83
49
  void ros_shutdown ()
84
  {
85
590
    for(std::map<std::string, std::unique_ptr<GlobalRos> >::iterator
86
262
        it=GLOBAL_ROS_VAR.begin() ; it!=GLOBAL_ROS_VAR.end() ; ++it)
87
    {
88
164
      it->second.reset(nullptr);
89
    }
90
49
    GLOBAL_ROS_VAR.clear();
91
49
  }
92
93
328
  bool ros_exist (std::string node_name)
94
  {
95

328
    if(GLOBAL_ROS_VAR.find(node_name) == GLOBAL_ROS_VAR.end())
96
    {
97
286
      return false;
98
    }
99
42
    if(GLOBAL_ROS_VAR.at(node_name) == nullptr)
100
    {
101
      return false;
102
    }
103
42
    return true;
104
  }
105

9
} // end of namespace dynamic_graph.