Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#include <map>
#include <memory>
#include <set>
#include <vector>
TESSERACT_COMMON_IGNORE_WARNINGS_POP

#include <tesseract_common/fwd.h>
Expand Down Expand Up @@ -72,6 +73,8 @@ class TaskComposerNodeFactory
const YAML::Node& config,
const TaskComposerPluginFactory& plugin_factory) const = 0;

virtual std::unique_ptr<TaskComposerNode> create() const = 0;

protected:
static std::string getSection();
friend class boost_plugin_loader::PluginLoader;
Expand All @@ -89,6 +92,8 @@ class TaskComposerExecutorFactory

virtual std::unique_ptr<TaskComposerExecutor> create(const std::string& name, const YAML::Node& config) const = 0;

virtual std::unique_ptr<TaskComposerExecutor> create() const = 0;

protected:
static std::string getSection();
friend class boost_plugin_loader::PluginLoader;
Expand Down Expand Up @@ -307,6 +312,16 @@ class TaskComposerPluginFactory
*/
YAML::Node getConfig() const;

/**
* @brief Returns a list of available task composer node plugins
*/
std::vector<std::string> getAvailableTaskComposerNodePlugins() const;

/**
* @brief Returns a list of available task composer executor plugins
*/
std::vector<std::string> getAvailableTaskComposerExecutorPlugins() const;

private:
struct Implementation;
std::unique_ptr<Implementation> impl_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class TaskComposerTaskFactory : public TaskComposerNodeFactory
{
return std::make_unique<TaskType>(name, config, plugin_factory);
}

std::unique_ptr<TaskComposerNode> create() const override { return std::make_unique<TaskType>(); }
};

template <typename ExecutorType>
Expand All @@ -50,6 +52,8 @@ class TaskComposerExecutorFactoryImpl : public TaskComposerExecutorFactory
{
return std::make_unique<ExecutorType>(name, config);
}

std::unique_ptr<TaskComposerExecutor> create() const override { return std::make_unique<ExecutorType>(); }
};
} // namespace tesseract_planning

Expand Down
93 changes: 77 additions & 16 deletions tesseract_task_composer/core/src/task_composer_plugin_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,17 +282,42 @@ std::string TaskComposerPluginFactory::getDefaultTaskComposerNodePlugin() const
std::unique_ptr<TaskComposerExecutor>
TaskComposerPluginFactory::createTaskComposerExecutor(const std::string& name) const
{
const auto& executor_plugin_info = impl_->executor_plugin_info;
auto cm_it = executor_plugin_info.plugins.find(name);
if (cm_it == executor_plugin_info.plugins.end())
try
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with this change is that the plugins are not intended to be reconfigurable after being created which can lead to incorrect usage. Instead what if this method generated a meta package (which needs to be defined) that this function produces. Once option I explored in the past was leveraging a yaml file which include this information which could also be used for the yaml editor in tesseract_qt.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the schema I was exploring at the time. I think it would be good to discuss a little more because this could benefit all plugins throughout tesseract.

https://github.com/tesseract-robotics/tesseract_planning/blob/master/tesseract_task_composer/config/task_composer_plugins.yaml.schema

{
// Check if the input name has associated plugin information
const auto& executor_plugin_info = impl_->executor_plugin_info;
auto cm_it = executor_plugin_info.plugins.find(name);
if (cm_it != executor_plugin_info.plugins.end())
return createTaskComposerExecutor(name, cm_it->second);

// Check if a plugin factory has already been loaded for the input plugin name
auto& executor_factories = impl_->executor_factories;
auto it = executor_factories.find(name);
if (it != executor_factories.end())
{
// Default create a task composer node from the plugin since no configuration information exists
return it->second->create();
}

// Load the plugin since one has not already been loaded
auto plugin = impl_->plugin_loader.instantiate<TaskComposerExecutorFactory>(name);
if (plugin == nullptr)
{
CONSOLE_BRIDGE_logWarn("Failed to load symbol '%s'", name.c_str());
return nullptr;
}

// Store the plugin internally to keep the plugin in scope for the lifetime of this factory object
executor_factories[name] = plugin;

// Default create a task composer node from the plugin since no configuration information exists
return plugin->create();
}
catch (const std::exception& e)
{
CONSOLE_BRIDGE_logWarn("TaskComposerPluginFactory, tried to get task composer executor '%s' that does not "
"exist!",
name.c_str());
CONSOLE_BRIDGE_logWarn("Failed to load symbol '%s', Details: %s", name.c_str(), e.what());
return nullptr;
}

return createTaskComposerExecutor(name, cm_it->second);
}

std::unique_ptr<TaskComposerExecutor>
Expand Down Expand Up @@ -324,17 +349,42 @@ TaskComposerPluginFactory::createTaskComposerExecutor(const std::string& name,

std::unique_ptr<TaskComposerNode> TaskComposerPluginFactory::createTaskComposerNode(const std::string& name) const
{
const auto& task_plugin_info = impl_->task_plugin_info;
auto cm_it = task_plugin_info.plugins.find(name);
if (cm_it == task_plugin_info.plugins.end())
try
{
CONSOLE_BRIDGE_logWarn("TaskComposerPluginFactory, tried to get task composer node '%s' that does not "
"exist!",
name.c_str());
// Check if the input name has associated plugin information
const auto& task_plugin_info = impl_->task_plugin_info;
auto cm_it = task_plugin_info.plugins.find(name);
if (cm_it != task_plugin_info.plugins.end())
return createTaskComposerNode(name, cm_it->second);

// Check if a plugin factory has already been loaded for the input plugin name
auto& node_factories = impl_->node_factories;
auto it = node_factories.find(name);
if (it != node_factories.end())
{
// Default create a task composer node from the plugin since no configuration information exists
return it->second->create();
}

// Load the plugin since one has not already been loaded
auto plugin = impl_->plugin_loader.instantiate<TaskComposerNodeFactory>(name);
if (plugin == nullptr)
{
CONSOLE_BRIDGE_logWarn("Failed to load symbol '%s'", name.c_str());
return nullptr;
}

// Store the plugin internally to keep the plugin in scope for the lifetime of this factory object
node_factories[name] = plugin;

// Default create a task composer node from the plugin since no configuration information exists
return plugin->create();
}
catch (const std::exception& e)
{
CONSOLE_BRIDGE_logWarn("Failed to load symbol '%s', Details: %s", name.c_str(), e.what());
return nullptr;
}

return createTaskComposerNode(name, cm_it->second);
}

std::unique_ptr<TaskComposerNode>
Expand Down Expand Up @@ -384,4 +434,15 @@ YAML::Node TaskComposerPluginFactory::getConfig() const

return config;
}

std::vector<std::string> TaskComposerPluginFactory::getAvailableTaskComposerNodePlugins() const
{
return impl_->plugin_loader.getAvailablePlugins("TaskNode");
}

std::vector<std::string> TaskComposerPluginFactory::getAvailableTaskComposerExecutorPlugins() const
{
return impl_->plugin_loader.getAvailablePlugins("TaskExec");
}

} // namespace tesseract_planning
Loading