9 #include <boost/asio/ip/host_name.hpp>
10 #include <boost/interprocess/detail/os_thread_functions.hpp>
11 #include <boost/filesystem.hpp>
12 #include <boost/lexical_cast.hpp>
13 #include <boost/uuid/uuid.hpp>
14 #include <boost/uuid/uuid_generators.hpp>
15 #include <boost/uuid/uuid_io.hpp>
16 #include <ros/package.h>
29 boost::filesystem::path expandHome(
const boost::filesystem::path &in)
34 RBX_WARN(
"HOME Environment variable is not set! Cannot resolve ~ in path.");
38 boost::filesystem::path out;
39 for (
const auto &p : in)
40 out /= (p.string() ==
"~") ? home : p;
45 boost::filesystem::path expandSymlinks(
const boost::filesystem::path &in)
48 boost::filesystem::path out;
49 for (
const auto &p : in)
52 if (boost::filesystem::is_symlink(tmp))
53 return boost::filesystem::canonical(in);
59 boost::filesystem::path expandPath(
const boost::filesystem::path &in)
61 boost::filesystem::path out = in;
62 out = expandHome(out);
63 out = expandSymlinks(out);
65 return boost::filesystem::absolute(out);
82 boost::filesystem::path path(path_string);
83 const std::string last = boost::filesystem::extension(path);
84 return isSuffix(extension, last);
95 boost::filesystem::path file;
96 if (isPrefix(prefix, path))
99 const std::string package_name = (*subpath.begin()).
string();
101 const std::string package = ros::package::getPath(package_name);
104 RBX_WARN(
"Package `%s` does not exist.", package_name);
109 for (
auto it = ++subpath.begin(); it != subpath.end(); ++it)
115 return expandPath(file).
string();
120 const std::regex re(R
"(((package):?\/)\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)?)");
127 for (
auto it = begin; it != end; ++it)
141 if (!boost::filesystem::exists(file))
143 RBX_WARN(
"File `%s` does not exist.", path);
147 return boost::filesystem::canonical(boost::filesystem::absolute(file)).string();
153 return file.parent_path().string();
167 if (full_path.
empty())
170 std::ifstream ifs(full_path.
c_str(), std::ios::in | std::ios::binary | std::ios::ate);
172 std::ifstream::pos_type size = ifs.
tellg();
173 ifs.
seekg(0, std::ios::beg);
188 RBX_ERROR(
"Failed to run command `%s`!", cmd);
192 while (!feof(pipe.
get()))
194 if (fgets(buffer.
data(), 128, pipe.
get()) !=
nullptr)
195 result += buffer.
data();
204 if (full_path.
empty())
209 #if ROBOWFLEX_AT_LEAST_MELODIC
221 if (full_path.
empty())
224 if (isExtension(full_path,
"xacro"))
234 if (full_path.
empty())
237 if (!isExtension(full_path,
"yml") && !isExtension(full_path,
"yaml"))
254 if (full_path.
empty())
257 if (!isExtension(full_path,
"yml") && !isExtension(full_path,
"yaml"))
286 boost::uuids::random_generator gen;
287 boost::uuids::uuid u = gen();
289 std::string s = boost::lexical_cast<std::string>(u);
298 boost::filesystem::path path(file);
299 path = expandHome(path);
300 path = expandSymlinks(path);
302 const auto parent = path.parent_path().string();
305 boost::filesystem::create_directories(parent);
307 out.
open(path.string(), std::ofstream::out | std::ofstream::trunc);
312 auto temp = boost::filesystem::unique_path();
313 auto filename =
"/tmp/" + temp.string();
321 boost::filesystem::path path(file);
322 path = expandHome(path);
323 path = expandSymlinks(path);
325 boost::filesystem::remove(path);
333 if (full_path.
empty())
336 boost::filesystem::path path(full_path);
337 if (!boost::filesystem::is_directory(path))
340 for (
auto it = boost::filesystem::directory_iterator(path); it != boost::filesystem::directory_iterator();
349 return boost::asio::ip::host_name();
354 return boost::interprocess::ipcdetail::get_current_process_id();
359 return boost::interprocess::ipcdetail::get_current_thread_id();
364 return boost::posix_time::microsec_clock::local_time();
367 double IO::getSeconds(boost::posix_time::ptime start, boost::posix_time::ptime finish)
369 auto duration = finish - start;
370 return duration.total_microseconds() / 1000000.;
378 template <
typename T>
381 boost::char_separator<char> seps(separators.
c_str());
382 boost::tokenizer<boost::char_separator<char>> tokenizer(s, seps);
386 [](
const std::string &s) { return boost::lexical_cast<T>(s); });
400 , file_((mode_ == WRITE) ? file : IO::
resolvePath(file))
401 , bag_(file_, (mode_ == WRITE) ? rosbag::bagmode::Write : rosbag::bagmode::Read)
419 class XmlRpcValueCreator :
public XmlRpc::XmlRpcValue
424 XmlRpcValueCreator ret;
425 ret._type = TypeArray;
426 ret._value.asArray =
new ValueArray(values);
433 XmlRpcValueCreator ret;
434 ret._type = TypeStruct;
440 XmlRpc::XmlRpcValue YAMLToXmlRpc(
const YAML::Node &node)
442 if (node.Type() != YAML::NodeType::Scalar)
446 case YAML::NodeType::Map:
449 for (YAML::const_iterator it = node.begin(); it != node.end(); ++it)
450 members[it->first.as<
std::string>()] = YAMLToXmlRpc(it->second);
452 return XmlRpcValueCreator::createStruct(members);
454 case YAML::NodeType::Sequence:
457 for (YAML::const_iterator it = node.begin(); it != node.end(); ++it)
460 return XmlRpcValueCreator::createArray(values);
463 throw Exception(1,
"Unknown non-scalar node type in YAML");
467 if (node.Tag() ==
"!!int")
468 return XmlRpc::XmlRpcValue(node.as<
int>());
470 if (node.Tag() ==
"!!float")
471 return XmlRpc::XmlRpcValue(node.as<
double>());
473 if (node.Tag() ==
"!!bool")
474 return XmlRpc::XmlRpcValue(node.as<
bool>());
478 return XmlRpc::XmlRpcValue(node.as<
bool>());
480 catch (YAML::Exception &)
486 return XmlRpc::XmlRpcValue(node.as<
int>());
488 catch (YAML::Exception &)
494 return XmlRpc::XmlRpcValue(node.as<
double>());
496 catch (YAML::Exception &)
502 return XmlRpc::XmlRpcValue(node.as<
std::string>());
504 catch (YAML::Exception &)
508 throw Exception(1,
"Unknown node value in YAML");
513 : name_(name), namespace_(
"robowflex_" + UUID +
"/" + name_), nh_(namespace_)
518 : name_(handler.getName()), namespace_(handler.getNamespace()), nh_(handler.getHandle(), name)
524 for (
const auto &key : params_)
525 nh_.deleteParam(key);
532 case YAML::NodeType::Map:
535 for (YAML::const_iterator it = node.begin(); it != node.end(); ++it)
536 loadYAMLtoROS(it->second, fixed_prefix + it->first.as<
std::string>());
540 case YAML::NodeType::Sequence:
541 case YAML::NodeType::Scalar:
543 setParam(prefix, YAMLToXmlRpc(node));
547 throw Exception(1,
"Unknown node type in YAML");
553 return nh_.hasParam(key);
T back_inserter(T... args)
Exception that contains a message and an error code.
~Bag()
Destructor. Closes opened bag.
Bag(const std::string &file, Mode mode=WRITE)
Constructor.
ROS parameter server handler to handle namespacing and automatic parameter deletion.
const std::string & getName() const
Gets the name of the handler.
~Handler()
Destructor. Deletes all parameters created through this handler.
bool hasParam(const std::string &key) const
Checks if the parameter server has key.
const ros::NodeHandle & getHandle() const
Gets the node handle.
void loadYAMLtoROS(const YAML::Node &node, const std::string &prefix="")
Loads the contents of a YAML node to the parameter server under a prefix.
const std::string & getNamespace() const
Gets the namespace of the handler.
Handler(const std::string &name)
Constructor.
static const std::string UUID
UUID of handler.
T emplace_back(T... args)
#define RBX_WARN(fmt,...)
Output a warning logging message.
#define RBX_ERROR(fmt,...)
Output a error logging message.
bool YAMLToFile(const YAML::Node &node, const std::string &file)
Write the contents of a YAML node out to a potentially new file.
double getSeconds(boost::posix_time::ptime start, boost::posix_time::ptime finish)
Get a duration in seconds from two times.
std::string resolveParent(const std::string &path)
Resolves package:// URLs to get the directory this path is in.
std::set< std::string > findPackageURIs(const std::string &string)
Finds all package URIs within a string.
boost::posix_time::ptime getDate()
Get the current time (up to milliseconds)
std::string resolvePackage(const std::string &path)
Resolves package:// URLs to their canonical form. The path does not need to exist,...
void deleteFile(const std::string &file)
Deletes a file.
std::size_t getProcessID()
Get the process ID of this process.
std::pair< bool, std::vector< YAML::Node > > loadAllFromFileToYAML(const std::string &path)
Loads a file with multiple documents to a vector of YAML nodes.
std::pair< bool, YAML::Node > loadFileToYAML(const std::string &path)
Loads a file to a YAML node.
std::string makeFilepath(const std::string &directory, const std::string &filename)
Concatenates two elements of a path, a directory and a filename.
std::string runCommand(const std::string &cmd)
Runs a command cmd and returns stdout as a string.
std::string getHostname()
Get the hostname of the system.
std::pair< bool, std::vector< std::string > > listDirectory(const std::string &directory)
Lists of the contents of a directory.
std::vector< T > tokenize(const std::string &string, const std::string &separators=" ")
Separates a string into casted tokens, based upon separators.
std::string loadFileToString(const std::string &path)
Loads a file to a string.
std::string generateUUID()
Generates a UUID.
std::size_t getThreadID()
Get the thread ID of the current thread.
std::string createTempFile(std::ofstream &out)
Creates a temporary file and opens an output stream.
std::string resolvePath(const std::string &path)
Resolves package:// URLs and relative file paths to their canonical form.
std::string loadXMLToString(const std::string &path)
Loads an XML or .xacro file to a string.
void createFile(std::ofstream &out, const std::string &file)
Creates a file and opens an output stream. Creates directories if they do not exist.
std::string loadXacroToString(const std::string &path)
Loads a .xacro file to a string.
void threadSleep(double seconds)
Put the current thread to sleep for a desired amount of seconds.
Main namespace. Contains all library classes and functions.