39 #include <tf2_ros/transform_listener.h>
42 #include <boost/tokenizer.hpp>
48 static const std::string ROBOT_DESCRIPTION =
51 static const rclcpp::Logger LOGGER = rclcpp::get_logger(
"move_group.move_group");
57 static const char*
const DEFAULT_CAPABILITIES[] = {
58 "move_group/MoveGroupCartesianPathService",
59 "move_group/MoveGroupKinematicsService",
60 "move_group/MoveGroupExecuteTrajectoryAction",
61 "move_group/MoveGroupMoveAction",
62 "move_group/MoveGroupPlanService",
63 "move_group/MoveGroupQueryPlannersService",
64 "move_group/MoveGroupStateValidationService",
65 "move_group/MoveGroupGetPlanningSceneService",
66 "move_group/ApplyPlanningSceneService",
67 "move_group/ClearOctomapService",
77 bool allow_trajectory_execution;
78 moveit_cpp->getNode()->get_parameter_or(
"allow_trajectory_execution", allow_trajectory_execution,
true);
81 std::make_shared<MoveGroupContext>(
moveit_cpp, default_planning_pipeline, allow_trajectory_execution, debug);
84 configureCapabilities();
89 capabilities_.clear();
91 capability_plugin_loader_.reset();
98 if (context_->status())
100 if (capabilities_.empty())
113 RCLCPP_ERROR(LOGGER,
"No MoveGroup context created. Nothing will work.");
122 void configureCapabilities()
126 capability_plugin_loader_ = std::make_shared<pluginlib::ClassLoader<MoveGroupCapability>>(
127 "moveit_ros_move_group",
"move_group::MoveGroupCapability");
129 catch (pluginlib::PluginlibException& ex)
131 RCLCPP_FATAL_STREAM(LOGGER,
"Exception while creating plugin loader for move_group capabilities: " << ex.what());
135 std::set<std::string> capabilities;
138 for (
const char* capability : DEFAULT_CAPABILITIES)
139 capabilities.insert(capability);
142 std::string capability_plugins;
143 if (context_->moveit_cpp_->getNode()->get_parameter(
"capabilities", capability_plugins))
145 boost::char_separator<char> sep(
" ");
146 boost::tokenizer<boost::char_separator<char>> tok(capability_plugins, sep);
147 capabilities.insert(tok.begin(), tok.end());
151 for (
const auto& pipeline_entry : context_->moveit_cpp_->getPlanningPipelines())
153 const auto& pipeline_name = pipeline_entry.first;
154 std::string pipeline_capabilities;
155 if (context_->moveit_cpp_->getNode()->get_parameter(pipeline_name +
".capabilities", pipeline_capabilities))
157 boost::char_separator<char> sep(
" ");
158 boost::tokenizer<boost::char_separator<char>> tok(pipeline_capabilities, sep);
159 capabilities.insert(tok.begin(), tok.end());
164 if (context_->moveit_cpp_->getNode()->get_parameter(
"disable_capabilities", capability_plugins))
166 boost::char_separator<char> sep(
" ");
167 boost::tokenizer<boost::char_separator<char>> tok(capability_plugins, sep);
168 for (boost::tokenizer<boost::char_separator<char>>::iterator cap_name = tok.begin(); cap_name != tok.end();
170 capabilities.erase(*cap_name);
173 for (
const std::string& capability : capabilities)
178 MoveGroupCapabilityPtr cap = capability_plugin_loader_->createUniqueInstance(capability);
179 cap->setContext(context_);
181 capabilities_.push_back(cap);
183 catch (pluginlib::PluginlibException& ex)
185 RCLCPP_ERROR_STREAM(LOGGER,
186 "Exception while loading move_group capability '" << capability <<
"': " << ex.what());
190 std::stringstream ss;
193 ss <<
"********************************************************" <<
'\n';
194 ss <<
"* MoveGroup using: " <<
'\n';
195 for (
const MoveGroupCapabilityPtr& cap : capabilities_)
196 ss <<
"* - " << cap->getName() <<
'\n';
197 ss <<
"********************************************************" <<
'\n';
198 RCLCPP_INFO(LOGGER,
"%s", ss.str().c_str());
201 MoveGroupContextPtr context_;
202 std::shared_ptr<pluginlib::ClassLoader<MoveGroupCapability>> capability_plugin_loader_;
203 std::vector<MoveGroupCapabilityPtr> capabilities_;
207 int main(
int argc,
char** argv)
209 rclcpp::init(argc, argv);
211 rclcpp::NodeOptions opt;
212 opt.allow_undeclared_parameters(
true);
213 opt.automatically_declare_parameters_from_overrides(
true);
214 rclcpp::Node::SharedPtr nh = rclcpp::Node::make_shared(
"move_group", opt);
219 std::vector<std::string> planning_pipeline_configs;
220 if (nh->get_parameter(
"planning_pipelines", planning_pipeline_configs))
222 if (planning_pipeline_configs.empty())
224 RCLCPP_ERROR(LOGGER,
"Failed to read parameter 'move_group.planning_pipelines'");
228 for (
const auto& config : planning_pipeline_configs)
237 std::string default_planning_pipeline;
238 if (nh->get_parameter(
"default_planning_pipeline", default_planning_pipeline))
241 if (std::find(pipeline_names.begin(), pipeline_names.end(), default_planning_pipeline) == pipeline_names.end())
244 "MoveGroup launched with ~default_planning_pipeline '%s' not configured in ~planning_pipelines",
245 default_planning_pipeline.c_str());
246 default_planning_pipeline =
"";
249 else if (pipeline_names.size() > 1)
253 "MoveGroup launched without ~default_planning_pipeline specifying the namespace for the default "
254 "planning pipeline configuration");
258 if (default_planning_pipeline.empty())
260 if (!pipeline_names.empty())
262 RCLCPP_WARN(LOGGER,
"Using default pipeline '%s'", pipeline_names[0].c_str());
263 default_planning_pipeline = pipeline_names[0];
267 RCLCPP_WARN(LOGGER,
"Falling back to using the the move_group node namespace (deprecated behavior).");
268 default_planning_pipeline =
"move_group";
274 nh->set_parameter(rclcpp::Parameter(
"default_planning_pipeline", default_planning_pipeline));
278 const auto tf_buffer = std::make_shared<tf2_ros::Buffer>(nh->get_clock(), tf2::durationFromSec(10.0));
279 const auto moveit_cpp = std::make_shared<moveit_cpp::MoveItCpp>(nh, moveit_cpp_options, tf_buffer);
285 for (
int i = 1; i < argc; ++i)
287 if (strncmp(argv[i],
"--debug", 7) == 0)
296 RCLCPP_INFO(LOGGER,
"MoveGroup debug mode is ON");
300 RCLCPP_INFO(LOGGER,
"MoveGroup debug mode is OFF");
303 rclcpp::executors::MultiThreadedExecutor executor;
307 bool monitor_dynamics;
308 if (nh->get_parameter(
"monitor_dynamics", monitor_dynamics) && monitor_dynamics)
310 RCLCPP_INFO(LOGGER,
"MoveGroup monitors robot dynamics (higher load)");
317 executor.add_node(nh);
323 RCLCPP_ERROR(LOGGER,
"Planning scene not configured");
MoveGroupContextPtr getContext()
MoveGroupExe(const moveit_cpp::MoveItCppPtr &moveit_cpp, const std::string &default_planning_pipeline, bool debug)
#define MOVEIT_CONSOLE_COLOR_BLUE
#define MOVEIT_CONSOLE_COLOR_GREEN
#define MOVEIT_CONSOLE_COLOR_RESET
#define MOVEIT_CONSOLE_COLOR_CYAN
int main(int argc, char **argv)
Parameter container for initializing MoveItCpp.
PlanningPipelineOptions planning_pipeline_options
std::vector< std::string > pipeline_names
std::string parent_namespace