Skip to content

Commit

Permalink
ManagedSensorParserMap
Browse files Browse the repository at this point in the history
Destroy class loader only after instances of parsers.
  • Loading branch information
rhaschke committed Sep 22, 2022
1 parent d87677f commit dab0a4e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
16 changes: 14 additions & 2 deletions urdf/include/urdf/sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,29 @@
#include <string>
#include <map>
#include <urdf_parser/sensor_parser.h>
#include <pluginlib/class_loader.h>

namespace urdf {

// Maintain class loader together with created parser instances
class ManagedSensorParserMap : public SensorParserMap {
public:
std::unique_ptr<pluginlib::ClassLoader<urdf::SensorParser>> loader;
ManagedSensorParserMap();
~ManagedSensorParserMap();
ManagedSensorParserMap(const ManagedSensorParserMap&) = delete;
ManagedSensorParserMap(ManagedSensorParserMap &&) = default;
ManagedSensorParserMap &operator=(ManagedSensorParserMap &&) = default;
};

/** Retrieve sensor parsers available through the plugin-lib mechanism
whose name matches any of the names listed in allowed.
If allowed is empty (the default), all parsers will be returned.
*/
urdf::SensorParserMap getSensorParsers(const std::vector<std::string> &allowed = std::vector<std::string>());
urdf::ManagedSensorParserMap getSensorParsers(const std::vector<std::string> &allowed = std::vector<std::string>());

/** Conveniency method returning the SensorParserMap for the given sensor name */
urdf::SensorParserMap getSensorParser(const std::string &name);
urdf::ManagedSensorParserMap getSensorParser(const std::string &name);

/** parse <sensor> tags in URDF document */
SensorMap parseSensors(const std::string &xml, const urdf::SensorParserMap &parsers);
Expand Down
20 changes: 14 additions & 6 deletions urdf/src/sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,21 @@
#include "urdf/sensor.h"

#include <ros/ros.h>
#include <pluginlib/class_loader.h>
#include <boost/shared_ptr.hpp>
#include <algorithm>
#include <fstream>

namespace urdf {

ManagedSensorParserMap::ManagedSensorParserMap()
: loader(new pluginlib::ClassLoader<urdf::SensorParser>("urdf", "urdf::SensorParser"))
{}

ManagedSensorParserMap::~ManagedSensorParserMap() {
clear(); // first destroy parser instances
loader.reset(); // and subsequently the loader
}

SensorMap parseSensorsFromFile(const std::string &filename, const SensorParserMap &parsers)
{
SensorMap result;
Expand Down Expand Up @@ -87,13 +95,13 @@ SensorMap parseSensors(const std::string &xml_string, const SensorParserMap &par
return parseSensors(xml_doc, parsers);
}

SensorParserMap getSensorParsers(const std::vector<std::string> &allowed)
ManagedSensorParserMap getSensorParsers(const std::vector<std::string> &allowed)
{
pluginlib::ClassLoader<urdf::SensorParser> loader("urdf", "urdf::SensorParser");
SensorParserMap parserMap;
ManagedSensorParserMap parserMap;
try
{
const std::vector<std::string> &classes = loader.getDeclaredClasses();
const std::vector<std::string> &classes = parserMap.loader->getDeclaredClasses();
for (std::size_t i = 0 ; i < classes.size() ; ++i)
{
// skip this class if not listed in allowed
Expand All @@ -102,7 +110,7 @@ SensorParserMap getSensorParsers(const std::vector<std::string> &allowed)

urdf::SensorParserSharedPtr parser;
try {
parser = loader.createInstance(classes[i]);
parser = parserMap.loader->createInstance(classes[i]);
} catch(const pluginlib::PluginlibException& ex) {
ROS_ERROR_STREAM("Failed to create sensor parser: " << classes[i] << "\n" << ex.what());
}
Expand All @@ -119,7 +127,7 @@ SensorParserMap getSensorParsers(const std::vector<std::string> &allowed)
return parserMap;
}

SensorParserMap getSensorParser(const std::string &name)
ManagedSensorParserMap getSensorParser(const std::string &name)
{
std::vector<std::string> allowed;
allowed.push_back(name);
Expand Down

0 comments on commit dab0a4e

Please sign in to comment.