39#include <std_msgs/msg/string.hpp>
40#include <ament_index_cpp/get_package_prefix.hpp>
55#include <ament_index_cpp/version.h>
56#if AMENT_INDEX_CPP_VERSION_GTE(1, 14, 0)
57#include <ament_index_cpp/get_package_share_path.hpp>
59#include <ament_index_cpp/get_package_share_directory.hpp>
63#include <rclcpp/duration.hpp>
64#include <rclcpp/logger.hpp>
65#include <rclcpp/logging.hpp>
66#include <rclcpp/node.hpp>
67#include <rclcpp/time.hpp>
87 bool default_continuous_value,
double default_timeout)
90 auto start = node->now();
92 urdf_string_ = urdf_ssp_.loadInitialValue(
93 node, ros_name, [
this](
const std::string& new_urdf_string) {
return urdfUpdateCallback(new_urdf_string); },
94 default_continuous_value, default_timeout);
96 const std::string srdf_name = ros_name +
"_semantic";
97 srdf_string_ = srdf_ssp_.loadInitialValue(
98 node, srdf_name, [
this](
const std::string& new_srdf_string) {
return srdfUpdateCallback(new_srdf_string); },
99 default_continuous_value, default_timeout);
101 if (!loadFromStrings())
106 RCLCPP_INFO_STREAM(
getLogger(),
"Loaded robot model in " << (node->now() - start).seconds() <<
" seconds");
110 : urdf_string_(urdf_string), srdf_string_(srdf_string)
112 if (!loadFromStrings())
118bool RDFLoader::loadFromStrings()
120 std::unique_ptr<urdf::Model> urdf = std::make_unique<urdf::Model>();
121 if (!urdf->initString(urdf_string_))
123 RCLCPP_INFO(
getLogger(),
"Unable to parse URDF");
127 srdf::ModelSharedPtr srdf = std::make_shared<srdf::Model>();
128 if (!srdf->initString(*urdf, srdf_string_))
130 RCLCPP_ERROR(
getLogger(),
"Unable to parse SRDF");
134 urdf_ = std::move(urdf);
135 srdf_ = std::move(srdf);
141 std::string lower_path = path;
142 std::transform(lower_path.begin(), lower_path.end(), lower_path.begin(), ::tolower);
144 return lower_path.find(
".xacro") != std::string::npos;
151 RCLCPP_ERROR(
getLogger(),
"Path is empty");
155 if (!std::filesystem::exists(path))
157 RCLCPP_ERROR(
getLogger(),
"File does not exist");
161 std::ifstream stream(path.c_str());
164 RCLCPP_ERROR(
getLogger(),
"Unable to load path");
169 stream.seekg(0, std::ios::end);
170 buffer.reserve(stream.tellg());
171 stream.seekg(0, std::ios::beg);
172 buffer.assign((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
179 const std::vector<std::string>& xacro_args)
184 RCLCPP_ERROR(
getLogger(),
"Path is empty");
188 if (!std::filesystem::exists(path))
190 RCLCPP_ERROR(
getLogger(),
"File does not exist");
194 std::string cmd =
"ros2 run xacro xacro ";
195 for (
const std::string& xacro_arg : xacro_args)
196 cmd += xacro_arg +
" ";
200 FILE* pipe = _popen(cmd.c_str(),
"r");
202 FILE* pipe = popen(cmd.c_str(),
"r");
206 RCLCPP_ERROR(
getLogger(),
"Unable to load path");
210 char pipe_buffer[128];
213 if (fgets(pipe_buffer, 128, pipe) !=
nullptr)
214 buffer += pipe_buffer;
226 const std::vector<std::string>& xacro_args)
237 const std::string& relative_path,
const std::vector<std::string>& xacro_args)
239 std::filesystem::path path;
242#if AMENT_INDEX_CPP_VERSION_GTE(1, 14, 0)
243 path = ament_index_cpp::get_package_share_path(package_name);
244#elif AMENT_INDEX_CPP_VERSION_GTE(1, 5, 0)
245 ament_index_cpp::get_package_share_directory(package_name, path);
247 path = ament_index_cpp::get_package_share_directory(package_name);
250 catch (
const ament_index_cpp::PackageNotFoundError& e)
252 RCLCPP_ERROR(
getLogger(),
"ament_index_cpp: %s", e.what());
256 path = path / relative_path;
261void RDFLoader::urdfUpdateCallback(
const std::string& new_urdf_string)
263 urdf_string_ = new_urdf_string;
264 if (!loadFromStrings())
274void RDFLoader::srdfUpdateCallback(
const std::string& new_srdf_string)
276 srdf_string_ = new_srdf_string;
277 if (!loadFromStrings())
static bool loadXmlFileToString(std::string &buffer, const std::string &path, const std::vector< std::string > &xacro_args)
helper that branches between loadFileToString() and loadXacroFileToString() based on result of isXacr...
static bool isXacroFile(const std::string &path)
determine if given path points to a xacro file
static bool loadPkgFileToString(std::string &buffer, const std::string &package_name, const std::string &relative_path, const std::vector< std::string > &xacro_args)
helper that generates a file path based on package name and relative file path to package
RDFLoader(const std::shared_ptr< rclcpp::Node > &node, const std::string &ros_name="robot_description", bool default_continuous_value=false, double default_timeout=10.0)
Default constructor.
static bool loadFileToString(std::string &buffer, const std::string &path)
load file from given path into buffer
static bool loadXacroFileToString(std::string &buffer, const std::string &path, const std::vector< std::string > &xacro_args)
run xacro with the given args on the file, return result in buffer
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
rclcpp::Logger getLogger()