Program Listing for File node.hpp
↰ Return to documentation for file (/tmp/ws/src/gazebo_ros_pkgs/gazebo_ros/include/gazebo_ros/node.hpp
)
// Copyright 2018 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GAZEBO_ROS__NODE_HPP_
#define GAZEBO_ROS__NODE_HPP_
#include <rclcpp/rclcpp.hpp>
#include <gazebo_ros/executor.hpp>
#include <gazebo_ros/node_visibility_control.h>
#include <gazebo_ros/qos.hpp>
#include <atomic>
#include <memory>
#include <mutex>
#include <string>
#include <utility>
#include <vector>
#include <unordered_set>
namespace gazebo_ros
{
// forward declare ExistingNodes
class ExistingNodes;
class GAZEBO_ROS_NODE_PUBLIC Node : public rclcpp::Node
{
public:
using SharedPtr = std::shared_ptr<Node>;
virtual ~Node();
static SharedPtr Get();
static SharedPtr Get(sdf::ElementPtr _sdf, std::string _node_name = "");
template<typename ... Args>
static SharedPtr CreateWithArgs(Args && ... args);
/* \details SDF must have a type and name attribute
* where type is either 'int', 'float', 'double','bool' or 'string'.
* Note that 'float' and 'double' are both stored as double.
* Examples:
* \code{.xml}
* <parameter type="int" name="my_int">55</parameter>
* <parameter type="bool" name="my_bool">false</parameter>
* <parameter type="double" name="my_double">13.37</parameter>
* <parameter type="float" name="my_float">41.18</parameter>
* <parameter type="string" name="my_string">Hello World</parameter>
* \endcode
* \param[in] _sdf An sdf element in the style mentioned above
* \return The ROS parameter with the same name, type, and value as the sdf element
* On failure, the return parameter.get_type() == rclcpp::ParameterType::PARAMETER_NOT_SET
*/
static rclcpp::Parameter sdf_to_ros_parameter(sdf::ElementPtr const & _sdf);
inline const gazebo_ros::QoS & get_qos() const &
{
return this->qos_;
}
// binds to everything else
inline gazebo_ros::QoS get_qos() &&
{
return this->qos_;
}
private:
using rclcpp::Node::Node;
// A handler for the param change callback.
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr param_change_callback_handler_;
std::shared_ptr<Executor> executor_;
gazebo_ros::QoS qos_;
static ExistingNodes static_existing_nodes_;
static std::mutex lock_;
static std::weak_ptr<Executor> static_executor_;
static std::weak_ptr<Node> static_node_;
static rclcpp::Logger internal_logger();
};
template<typename ... Args>
Node::SharedPtr Node::CreateWithArgs(Args && ... args)
{
std::lock_guard<std::mutex> l(lock_);
// Contruct Node by forwarding arguments
// TODO(chapulina): use rclcpp::is_initialized() once that's available, see
// https://github.com/ros2/rclcpp/issues/518
Node::SharedPtr node;
if (!rclcpp::ok()) {
rclcpp::init(0, nullptr);
RCLCPP_INFO(internal_logger(), "ROS was initialized without arguments.");
}
node = std::make_shared<Node>(std::forward<Args>(args) ...);
node->set_parameter(rclcpp::Parameter("use_sim_time", true));
// Store shared pointer to static executor in this object
node->executor_ = static_executor_.lock();
// If executor has not been contructed yet, do so now
if (!node->executor_) {
node->executor_ = std::make_shared<Executor>();
static_executor_ = node->executor_;
}
// Generate warning on start up if use_sim_time parameter is set to false
bool check_sim_time;
node->get_parameter("use_sim_time", check_sim_time);
if (!check_sim_time) {
RCLCPP_WARN(
node->get_logger(), "Startup warning: use_sim_time parameter will be ignored "
"by default plugins and ROS messages will continue to use simulation timestamps");
}
std::weak_ptr<gazebo_ros::Node> node_weak_ptr;
node_weak_ptr = node;
// Parameter change callback
auto param_change_callback =
[&node_weak_ptr](std::vector<rclcpp::Parameter> parameters) {
auto result = rcl_interfaces::msg::SetParametersResult();
result.successful = true;
for (const auto & parameter : parameters) {
auto param_name = parameter.get_name();
if (param_name == "use_sim_time") {
if (auto node_shared_ptr = node_weak_ptr.lock()) {
RCLCPP_WARN(
node_shared_ptr->get_logger(),
"use_sim_time parameter will be ignored by default plugins "
"and ROS messages will continue to use simulation timestamps");
}
}
}
return result;
};
node->param_change_callback_handler_ =
node->add_on_set_parameters_callback(param_change_callback);
// Add new node to the executor so its callbacks are called
node->executor_->add_node(node);
return node;
}
// Class to hold the global set of tracked node names.
class ExistingNodes
{
public:
// Methods need to be protected by internal mutex
void add_node(const std::string & node_name);
bool check_node(const std::string & node_name);
void remove_node(const std::string & node_name);
private:
std::unordered_set<std::string> set_;
std::mutex internal_mutex_;
};
} // namespace gazebo_ros
#endif // GAZEBO_ROS__NODE_HPP_