40 #include <boost/thread/mutex.hpp>
50 static const std::string
LOGNAME =
"kinematics_plugin_loader";
52 class KinematicsPluginLoader::KinematicsLoaderImpl
63 const std::map<std::string, std::vector<std::string>>& possible_kinematics_solvers,
64 const std::map<std::string, std::vector<double>>& search_res,
65 const std::map<std::string, std::vector<std::string>>& iksolver_to_tip_links)
74 std::make_shared<pluginlib::ClassLoader<kinematics::KinematicsBase>>(
"moveit_core",
"kinematics::"
90 std::vector<std::string> tips;
99 <<
" based on values in rosparam server.");
100 tips = ik_it->second;
106 << jmg->
getName() <<
" based on last link in chain");
118 std::stringstream tip_debug;
119 tip_debug <<
"Planning group '" << jmg->
getName() <<
"' has tip(s): ";
120 for (
const std::string& tip : tips)
121 tip_debug << tip <<
", ";
129 kinematics::KinematicsBasePtr result;
140 const std::vector<const moveit::core::LinkModel*>& links = jmg->
getLinkModels();
150 std::map<std::string, std::vector<std::string>>::const_iterator it =
158 const std::string& base = links.front()->getParentJointModel()->getParentLinkModel() ?
159 links.front()->getParentJointModel()->getParentLinkModel()->getName() :
163 boost::mutex::scoped_lock slock(
lock_);
164 for (std::size_t i = 0; !result && i < it->second.size(); ++i)
178 (base.empty() || base[0] !=
'/') ? base : base.substr(1), tips, search_res) &&
181 (base.empty() || base[0] !=
'/') ? base : base.substr(1), tips, search_res))
184 it->second[i].c_str(), jmg->
getName().c_str());
191 "Successfully allocated and initialized a kinematics solver of type '%s' with search "
192 "resolution %lf for group '%s' at address %p",
193 it->second[i].c_str(), search_res, jmg->
getName().c_str(), result.get());
199 ROS_ERROR_NAMED(
LOGNAME,
"The kinematics plugin (%s) failed to load. Error: %s", it->first.c_str(), e.what());
206 "Did you load kinematics.yaml into your node's namespace?");
219 return std::move(cached);
230 for (std::size_t i = 0; i < it->second.size(); ++i)
232 it->second[i].c_str(),
search_res_.at(it->first)[i]);
238 std::map<std::string, std::vector<double>>
search_res_;
241 std::shared_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase>>
kinematics_loader_;
242 std::map<const moveit::core::JointModelGroup*, kinematics::KinematicsBasePtr>
instances_;
262 return loader.allocKinematicsSolverWithCache(jmg);
280 std::map<std::string, std::vector<std::string>> possible_kinematics_solvers;
281 std::map<std::string, std::vector<double>> search_res;
282 std::map<std::string, std::vector<std::string>> iksolver_to_tip_links;
286 const std::vector<srdf::Model::Group>& known_groups = srdf_model->getGroups();
300 std::string base_param_name = known_group.name_;
302 (base_param_name +
"/kinematics_solver").c_str());
303 std::string ksolver_param_name;
304 bool found = nh.
searchParam(base_param_name +
"/kinematics_solver", ksolver_param_name);
305 if (!found || !nh.
hasParam(ksolver_param_name))
309 found = nh.
searchParam(base_param_name +
"/kinematics_solver", ksolver_param_name);
315 if (nh.
getParam(ksolver_param_name, ksolver))
317 std::stringstream ss(ksolver);
319 while (ss.good() && !ss.eof())
324 groups_.push_back(known_group.name_);
327 ss >> solver >> std::ws;
328 possible_kinematics_solvers[known_group.name_].push_back(solver);
330 known_group.name_.c_str());
335 std::string ksolver_timeout_param_name;
336 if (nh.
searchParam(base_param_name +
"/kinematics_solver_timeout", ksolver_timeout_param_name))
338 double ksolver_timeout;
339 if (nh.
getParam(ksolver_timeout_param_name, ksolver_timeout))
343 int ksolver_timeout_i;
344 if (nh.
getParam(ksolver_timeout_param_name, ksolver_timeout_i))
345 ik_timeout_[known_group.name_] = ksolver_timeout_i;
350 std::string ksolver_attempts_param_name;
351 if (nh.
searchParam(base_param_name +
"/kinematics_solver_attempts", ksolver_attempts_param_name) &&
352 nh.
hasParam(ksolver_attempts_param_name))
355 "Kinematics solver doesn't support #attempts anymore, but only a timeout.\n"
356 "Please remove the parameter '%s' from your configuration.",
357 ksolver_attempts_param_name.c_str());
360 std::string ksolver_res_param_name;
361 if (nh.
searchParam(base_param_name +
"/kinematics_solver_search_resolution", ksolver_res_param_name))
363 std::string ksolver_res;
364 if (nh.
getParam(ksolver_res_param_name, ksolver_res))
366 std::stringstream ss(ksolver_res);
367 while (ss.good() && !ss.eof())
370 ss >> res >> std::ws;
371 search_res[known_group.name_].push_back(res);
377 if (nh.
getParam(ksolver_res_param_name, res))
378 search_res[known_group.name_].push_back(res);
382 if (nh.
getParam(ksolver_res_param_name, res_i))
383 search_res[known_group.name_].push_back(res_i);
390 std::string ksolver_ik_link_param_name;
391 if (nh.
searchParam(base_param_name +
"/kinematics_solver_ik_link", ksolver_ik_link_param_name))
393 std::string ksolver_ik_link;
394 if (nh.
getParam(ksolver_ik_link_param_name, ksolver_ik_link))
397 "deprecated in favor of kinematics_solver_ik_links "
399 iksolver_to_tip_links[known_group.name_].push_back(ksolver_ik_link);
404 std::string ksolver_ik_links_param_name;
405 if (nh.
searchParam(base_param_name +
"/kinematics_solver_ik_links", ksolver_ik_links_param_name))
408 if (nh.
getParam(ksolver_ik_links_param_name, ksolver_ik_links))
413 <<
"' should be an XmlRpc "
414 "value type 'Array'");
418 for (int32_t j = 0; j < ksolver_ik_links.
size(); ++j)
422 <<
" for group " << known_group.name_);
423 iksolver_to_tip_links[known_group.name_].push_back(
static_cast<std::string
>(ksolver_ik_links[j]));
431 while (search_res[known_group.name_].size() < possible_kinematics_solvers[known_group.name_].size())
443 groups_.push_back(known_group.name_);
449 iksolver_to_tip_links);
453 return loader.allocKinematicsSolverWithCache(jmg);