29 using PluginConfigs = std::vector< std::pair<std::string,XmlRpc::XmlRpcValue> >;
31 static const std::string COST_FUNCTIONS_FIELD =
"cost_functions";
32 static const std::string NOISY_FILTERS_FIELD =
"noisy_filters";
33 static const std::string UPDATE_FILTERS_FIELD =
"update_filters";
34 static const std::string NOISE_GENERATOR_FIELD =
"noise_generator";
44 std::string param_name,
45 PluginConfigs& plugins)
50 std::string class_name;
53 for(
auto i = 0u ; i < plugin_list.
size(); i++)
58 class_name =
static_cast<std::string
>(plugin_config[
"class"]);
59 plugins.push_back(std::make_pair(class_name,plugin_config));
63 ROS_ERROR(
"Element in the '%s' array parameter did not contain a 'class' entry",param_name.c_str());
70 ROS_WARN(
"Plugin under entry '%s' was not found in ros parameter.",param_name.c_str());
71 ROS_DEBUG(
"Failed to find plugin under entry '%s' in ros parameter %s",param_name.c_str(),config.
toXml().c_str());
75 return !plugins.empty();
92 std::string param_key;
95 std::string plugin_desc;
96 moveit::core::RobotModelConstPtr robot_model;
97 std::string group_name;
100 template <
typename PluginPtr,
typename ClassLoaderPtr>
101 bool loadPlugins(
const PluginData plugin_data,
102 ClassLoaderPtr
class_loader ,std::vector<PluginPtr>& plugin_array)
104 PluginConfigs plugins;
109 for(
auto& entry: plugins)
115 plugin.reset(
class_loader->createUnmanagedInstance(entry.first));
119 if(plugin_data.critical)
121 ROS_ERROR(
"%s plugin '%s' could not be created",plugin_data.plugin_desc.c_str() ,entry.first.c_str());
126 ROS_WARN(
"%s plugin '%s' could not be created",plugin_data.plugin_desc.c_str() ,entry.first.c_str());
132 if(plugin->initialize(plugin_data.robot_model,plugin_data.group_name,entry.second))
134 plugin_array.push_back(plugin);
135 ROS_INFO_STREAM(
"Stomp Optimization Task loaded "<< plugin_data.plugin_desc <<
" '"<<plugin->getName()<<
"' plugin");
139 if(plugin_data.critical)
141 ROS_ERROR(
"%s plugin '%s' failed to initialize",plugin_data.plugin_desc.c_str(), entry.first.c_str());
146 ROS_WARN(
"%s plugin '%s' failed to initialize",plugin_data.plugin_desc.c_str(), entry.first.c_str());
151 if(plugin_data.single_instance)
157 std::stringstream ss;
159 auto arrayToString = [&ss](PluginConfigs::value_type& p)
164 std::for_each(plugins.begin(),plugins.end(),arrayToString);
167 ROS_DEBUG(
"Loaded %s plugins: %s", plugin_data.plugin_desc.c_str(), ss.str().c_str());
180 StompOptimizationTask::StompOptimizationTask(
181 moveit::core::RobotModelConstPtr robot_model_ptr,
182 std::string group_name,
184 robot_model_ptr_(robot_model_ptr),
185 group_name_(group_name)
188 cost_function_loader_.reset(
new CostFunctionLoader(
"stomp_moveit",
"stomp_moveit::cost_functions::StompCostFunction"));
190 noisy_filter_loader_.reset(
new NoisyFilterLoader(
"stomp_moveit",
"stomp_moveit::noisy_filters::StompNoisyFilter"));
191 update_filter_loader_.reset(
new UpdateFilterLoader(
"stomp_moveit",
"stomp_moveit::update_filters::StompUpdateFilter"));
195 plugin_data.config = config;
196 plugin_data.group_name = group_name_;
197 plugin_data.robot_model = robot_model_ptr_;
200 plugin_data.param_key = COST_FUNCTIONS_FIELD;
201 plugin_data.plugin_desc =
"CostFunction";
202 plugin_data.critical =
true;
203 plugin_data.single_instance =
false;
204 if(!loadPlugins(plugin_data,cost_function_loader_,cost_functions_))
206 ROS_ERROR(
"StompOptimizationTask/%s failed to load '%s' plugins from yaml",group_name.c_str(),COST_FUNCTIONS_FIELD.c_str());
207 throw std::logic_error(
"plugin not found");
211 plugin_data.param_key = NOISE_GENERATOR_FIELD;
212 plugin_data.plugin_desc =
"NoiseGenerator";
213 plugin_data.critical =
true;
214 plugin_data.single_instance =
true;
217 ROS_ERROR(
"StompOptimizationTask/%s failed to load '%s' plugins from yaml",group_name.c_str(),
218 NOISE_GENERATOR_FIELD.c_str());
219 throw std::logic_error(
"plugin not found");
223 plugin_data.param_key = NOISY_FILTERS_FIELD;
224 plugin_data.plugin_desc =
"NoisyFilter";
225 plugin_data.critical =
false;
226 plugin_data.single_instance =
false;
227 if(!loadPlugins(plugin_data,noisy_filter_loader_,noisy_filters_))
229 ROS_WARN(
"StompOptimizationTask/%s failed to load '%s' plugins from yaml",group_name.c_str(),NOISY_FILTERS_FIELD.c_str());
233 plugin_data.param_key = UPDATE_FILTERS_FIELD;
234 plugin_data.plugin_desc =
"UpdateFilter";
235 plugin_data.critical =
false;
236 plugin_data.single_instance =
false;
237 if(!loadPlugins(plugin_data,update_filter_loader_,update_filters_))
239 ROS_WARN(
"StompOptimizationTask/%s failed to load '%s' plugins from yaml",group_name.c_str(),UPDATE_FILTERS_FIELD.c_str());
243 StompOptimizationTask::~StompOptimizationTask()
249 std::size_t start_timestep,
250 std::size_t num_timesteps,
251 int iteration_number,
253 Eigen::MatrixXd& parameters_noise,
254 Eigen::MatrixXd& noise)
256 return noise_generators_.back()->generateNoise(parameters,start_timestep,num_timesteps,iteration_number,rollout_number,
257 parameters_noise,noise);
261 std::size_t start_timestep,
262 std::size_t num_timesteps,
263 int iteration_number,
265 Eigen::VectorXd& costs,
268 Eigen::MatrixXd cost_matrix = Eigen::MatrixXd::Zero(num_timesteps,cost_functions_.size());
269 Eigen::VectorXd state_costs = Eigen::VectorXd::Zero(num_timesteps);
271 for(
auto i = 0u; i < cost_functions_.size(); i++ )
274 auto cf = cost_functions_[i];
276 if(!cf->computeCosts(parameters,start_timestep,num_timesteps,iteration_number,rollout_number,state_costs,valid))
283 cost_matrix.col(i) = state_costs * cf->getWeight();
285 costs = cost_matrix.rowwise().sum();
290 std::size_t start_timestep,
291 std::size_t num_timesteps,
292 int iteration_number,
293 Eigen::VectorXd& costs,
296 Eigen::MatrixXd cost_matrix = Eigen::MatrixXd::Zero(num_timesteps,cost_functions_.size());
297 Eigen::VectorXd state_costs = Eigen::VectorXd::Zero(num_timesteps);
299 for(
auto i = 0u; i < cost_functions_.size(); i++ )
302 auto cf = cost_functions_[i];
304 if(!cf->computeCosts(parameters,start_timestep,num_timesteps,iteration_number,cf->getOptimizedIndex(),state_costs,valid))
311 cost_matrix.col(i) = state_costs * cf->getWeight();
313 costs = cost_matrix.rowwise().sum();
318 const moveit_msgs::MotionPlanRequest &req,
320 moveit_msgs::MoveItErrorCodes& error_code)
322 for(
auto p: noise_generators_)
324 if(!p->setMotionPlanRequest(planning_scene,req,config,error_code))
326 ROS_ERROR(
"Failed to set Plan Request on noise generator %s",p->getName().c_str());
331 for(
auto p : cost_functions_)
333 if(!p->setMotionPlanRequest(planning_scene,req,config,error_code))
335 ROS_ERROR(
"Failed to set Plan Request on cost function %s",p->getName().c_str());
340 for(
auto p: noisy_filters_)
342 if(!p->setMotionPlanRequest(planning_scene,req,config,error_code))
344 ROS_ERROR(
"Failed to set Plan Request on noisy filter %s",p->getName().c_str());
349 for(
auto p: update_filters_)
351 if(!p->setMotionPlanRequest(planning_scene,req,config,error_code))
353 ROS_ERROR(
"Failed to set Plan Request on update filter %s",p->getName().c_str());
362 std::size_t num_timesteps,
363 int iteration_number,
365 Eigen::MatrixXd& parameters,
bool& filtered)
369 for(
auto&
f: noisy_filters_)
371 if(
f->filter(start_timestep,num_timesteps,iteration_number,rollout_number,parameters,temp))
384 std::size_t num_timesteps,
385 int iteration_number,
386 const Eigen::MatrixXd& parameters,
387 Eigen::MatrixXd& updates)
389 bool filtered =
false;
391 for(
auto&
f: update_filters_)
393 if(
f->filter(start_timestep,num_timesteps,iteration_number,parameters,updates,temp))
406 std::size_t num_timesteps,
int iteration_number,
double cost,
const Eigen::MatrixXd& parameters)
408 for(
auto p : noise_generators_)
410 p->postIteration(start_timestep,num_timesteps,iteration_number,cost,parameters);
413 for(
auto p : cost_functions_)
415 p->postIteration(start_timestep,num_timesteps,iteration_number,cost,parameters);
418 for(
auto p: noisy_filters_)
420 p->postIteration(start_timestep,num_timesteps,iteration_number,cost,parameters);
423 for(
auto p: update_filters_)
425 p->postIteration(start_timestep,num_timesteps,iteration_number,cost,parameters);
431 for(
auto p : noise_generators_)
433 p->done(success,total_iterations,final_cost,parameters);
437 for(
auto p : cost_functions_)
439 p->done(success,total_iterations,final_cost,parameters);
442 for(
auto p: noisy_filters_)
444 p->done(success,total_iterations,final_cost,parameters);
447 for(
auto p: update_filters_)
449 p->done(success,total_iterations,final_cost,parameters);
virtual bool setMotionPlanRequest(const planning_scene::PlanningSceneConstPtr &planning_scene, const moveit_msgs::MotionPlanRequest &req, const stomp_core::StompConfiguration &config, moveit_msgs::MoveItErrorCodes &error_code)
Passes the planning details down to each loaded plugin.
Type const & getType() const
bool parsePluginConfigs(XmlRpc::XmlRpcValue config, std::string param_name, PluginConfigs &plugins)
Convenience method to load an array of STOMP plugins.
virtual bool filterNoisyParameters(std::size_t start_timestep, std::size_t num_timesteps, int iteration_number, int rollout_number, Eigen::MatrixXd ¶meters, bool &filtered) override
Filters the given noisy parameters which is applied after noisy trajectory generation. It could be used for clipping of joint limits or projecting into the null space of the Jacobian. It accomplishes this by calling the loaded Noisy Filter plugins.
virtual bool computeCosts(const Eigen::MatrixXd ¶meters, std::size_t start_timestep, std::size_t num_timesteps, int iteration_number, Eigen::VectorXd &costs, bool &validity) override
computes the state costs as a function of the optimized parameters for each time step. It does this by calling the loaded Cost Function plugins
Packs plugin information into a single struct.
virtual bool computeNoisyCosts(const Eigen::MatrixXd ¶meters, std::size_t start_timestep, std::size_t num_timesteps, int iteration_number, int rollout_number, Eigen::VectorXd &costs, bool &validity) override
computes the state costs as a function of the noisy parameters for each time step. It does this by calling the loaded Cost Function plugins
std::string toXml() const
NoiseGeneratorLoaderPtr noise_generator_loader_
virtual bool generateNoisyParameters(const Eigen::MatrixXd ¶meters, std::size_t start_timestep, std::size_t num_timesteps, int iteration_number, int rollout_number, Eigen::MatrixXd ¶meters_noise, Eigen::MatrixXd &noise) override
Generates a noisy trajectory from the parameters by calling the active Noise Generator plugin...
virtual void done(bool success, int total_iterations, double final_cost, const Eigen::MatrixXd ¶meters) override
Called by Stomp at the end of the optimization process.
virtual bool filterParameterUpdates(std::size_t start_timestep, std::size_t num_timesteps, int iteration_number, const Eigen::MatrixXd ¶meters, Eigen::MatrixXd &updates) override
Filters the given parameters which is applied after calculating the update. It could be used for clip...
virtual void postIteration(std::size_t start_timestep, std::size_t num_timesteps, int iteration_number, double cost, const Eigen::MatrixXd ¶meters)
Called by STOMP at the end of each iteration.
bool hasMember(const std::string &name) const
#define ROS_INFO_STREAM(args)
This defines stomp's optimization task.