63 const std::map<std::string, std::string>& possible_kinematics_solvers,
64 const std::map<std::string, double>& search_res,
const rclcpp::Logger& logger)
66 , robot_description_(robot_description)
67 , possible_kinematics_solvers_(possible_kinematics_solvers)
68 , search_res_(search_res)
74 std::make_shared<pluginlib::ClassLoader<kinematics::KinematicsBase>>(
"moveit_core",
"kinematics::"
77 catch (pluginlib::PluginlibException& e)
79 RCLCPP_ERROR(logger_,
"Unable to construct kinematics loader. Error: %s", e.what());
90 std::vector<std::string> tips;
93 "Choosing tip frame of kinematic solver for group %s"
94 "based on last link in chain",
102 RCLCPP_ERROR(logger_,
"Error choosing kinematic solver tip frame(s).");
106 std::stringstream tip_debug;
107 tip_debug <<
"Planning group '" << jmg->
getName() <<
"' has tip(s): ";
108 for (
const auto& tip : tips)
109 tip_debug << tip <<
", ";
110 RCLCPP_DEBUG_STREAM(logger_, tip_debug.str());
117 kinematics::KinematicsBasePtr result;
118 if (!kinematics_loader_)
120 RCLCPP_ERROR(logger_,
"Invalid kinematics loader.");
125 RCLCPP_ERROR(logger_,
"Specified group is nullptr. Cannot allocate kinematics solver.");
128 const std::vector<const moveit::core::LinkModel*>& links = jmg->
getLinkModels();
131 RCLCPP_ERROR(logger_,
"No links specified for group '%s'. Cannot allocate kinematics solver.",
136 RCLCPP_DEBUG(logger_,
"Trying to allocate kinematics solver for group '%s'", jmg->
getName().c_str());
138 const std::string& base = links.front()->getParentJointModel()->getParentLinkModel() ?
139 links.front()->getParentJointModel()->getParentLinkModel()->getName() :
143 std::scoped_lock slock(lock_);
144 for (
const auto& [group, solver] : possible_kinematics_solvers_)
153 result = kinematics_loader_->createUniqueInstance(solver);
160 double search_res = search_res_.find(jmg->
getName())->second;
163 (base.empty() || base[0] !=
'/') ? base : base.substr(1), tips, search_res))
165 RCLCPP_ERROR(logger_,
"Kinematics solver of type '%s' could not be initialized for group '%s'",
166 solver.c_str(), jmg->
getName().c_str());
172 RCLCPP_DEBUG(logger_,
173 "Successfully allocated and initialized a kinematics solver of type '%s' with search "
174 "resolution %lf for group '%s' at address %p",
175 solver.c_str(), search_res, jmg->
getName().c_str(), result.get());
179 catch (pluginlib::PluginlibException& e)
181 RCLCPP_ERROR(logger_,
"The kinematics plugin (%s) failed to load. Error: %s", solver.c_str(), e.what());
187 RCLCPP_DEBUG(logger_,
"No usable kinematics solver was found for this group.\n"
188 "Did you load kinematics.yaml into your node's namespace?");
198 std::scoped_lock slock(cache_lock_);
199 kinematics::KinematicsBasePtr& cached = instances_[jmg];
201 return std::move(cached);
210 for (
const auto& [group, solver] : possible_kinematics_solvers_)
212 RCLCPP_INFO(logger_,
"Solver for group '%s': '%s' (search resolution = %lf)", group.c_str(), solver.c_str(),
213 search_res_.at(group));
218 const rclcpp::Node::SharedPtr node_;
219 std::string robot_description_;
220 std::map<std::string, std::string> possible_kinematics_solvers_;
221 std::map<std::string, double> search_res_;
222 std::shared_ptr<pluginlib::ClassLoader<kinematics::KinematicsBase>> kinematics_loader_;
223 std::map<const moveit::core::JointModelGroup*, kinematics::KinematicsBasePtr> instances_;
225 std::mutex cache_lock_;
226 rclcpp::Logger logger_;
245 RCLCPP_DEBUG(logger_,
"Configuring kinematics solvers");
248 std::map<std::string, std::string> possible_kinematics_solvers;
249 std::map<std::string, double> search_res;
250 std::map<std::string, std::vector<std::string>> iksolver_to_tip_links;
254 const std::vector<srdf::Model::Group>& known_groups = srdf_model->getGroups();
256 RCLCPP_DEBUG(logger_,
"Loading kinematics parameters...");
258 for (
const srdf::Model::Group& known_group : known_groups)
260 std::string kinematics_param_prefix = robot_description_ +
"_kinematics." + known_group.name_;
261 group_param_listener_.try_emplace(known_group.name_,
262 std::make_shared<kinematics::ParamListener>(node_, kinematics_param_prefix));
263 group_params_.try_emplace(known_group.name_, group_param_listener_.at(known_group.name_)->get_params());
265 std::string kinematics_solver_param_name = kinematics_param_prefix +
".kinematics_solver";
266 const auto kinematics_solver = group_params_.at(known_group.name_).kinematics_solver;
268 if (kinematics_solver.empty())
270 RCLCPP_DEBUG(logger_,
"No kinematics solver specified for group '%s'.", known_group.name_.c_str());
275 groups_.push_back(known_group.name_);
277 possible_kinematics_solvers[known_group.name_] = kinematics_solver;
278 RCLCPP_DEBUG(logger_,
"Found kinematics solver '%s' for group '%s'.", kinematics_solver.c_str(),
279 known_group.name_.c_str());
281 std::string kinematics_solver_res_param_name = kinematics_param_prefix +
".kinematics_solver_search_resolution";
282 const auto kinematics_solver_search_resolution =
283 group_params_.at(known_group.name_).kinematics_solver_search_resolution;
284 search_res[known_group.name_] = kinematics_solver_search_resolution;
285 RCLCPP_DEBUG(logger_,
"Found param %s : %f", kinematics_solver_res_param_name.c_str(),
286 kinematics_solver_search_resolution);
288 std::string kinematics_solver_timeout_param_name = kinematics_param_prefix +
".kinematics_solver_timeout";
289 const auto kinematics_solver_timeout = group_params_.at(known_group.name_).kinematics_solver_timeout;
290 ik_timeout_[known_group.name_] = kinematics_solver_timeout;
291 RCLCPP_DEBUG(logger_,
"Found param %s : %f", kinematics_solver_timeout_param_name.c_str(),
292 kinematics_solver_timeout);
296 loader_ = std::make_shared<KinematicsLoaderImpl>(node_, robot_description_, possible_kinematics_solvers, search_res,
301 return loader.allocKinematicsSolverWithCache(jmg);
KinematicsLoaderImpl(const rclcpp::Node::SharedPtr &node, const std::string &robot_description, const std::map< std::string, std::string > &possible_kinematics_solvers, const std::map< std::string, double > &search_res, const rclcpp::Logger &logger)
Pimpl Implementation of KinematicsLoader.