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* 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())
109 RCLCPP_ERROR(LOGGER,
"No MoveGroup context created. Nothing will work.");
118 void configureCapabilities()
122 capability_plugin_loader_ = std::make_shared<pluginlib::ClassLoader<MoveGroupCapability>>(
123 "moveit_ros_move_group",
"move_group::MoveGroupCapability");
125 catch (pluginlib::PluginlibException& ex)
127 RCLCPP_FATAL_STREAM(LOGGER,
"Exception while creating plugin loader for move_group capabilities: " << ex.what());
131 std::set<std::string> capabilities;
134 for (
const char* capability : DEFAULT_CAPABILITIES)
135 capabilities.insert(capability);
138 std::string capability_plugins;
139 if (context_->moveit_cpp_->getNode()->get_parameter(
"capabilities", capability_plugins))
141 boost::char_separator<char> sep(
" ");
142 boost::tokenizer<boost::char_separator<char>> tok(capability_plugins, sep);
143 capabilities.insert(tok.begin(), tok.end());
147 for (
const auto& pipeline_entry : context_->moveit_cpp_->getPlanningPipelines())
149 const auto& pipeline_name = pipeline_entry.first;
150 std::string pipeline_capabilities;
151 if (context_->moveit_cpp_->getNode()->get_parameter(
"planning_pipelines/" + pipeline_name +
"/capabilities",
152 pipeline_capabilities))
154 boost::char_separator<char> sep(
" ");
155 boost::tokenizer<boost::char_separator<char>> tok(pipeline_capabilities, sep);
156 capabilities.insert(tok.begin(), tok.end());
161 if (context_->moveit_cpp_->getNode()->get_parameter(
"disable_capabilities", capability_plugins))
163 boost::char_separator<char> sep(
" ");
164 boost::tokenizer<boost::char_separator<char>> tok(capability_plugins, sep);
165 for (boost::tokenizer<boost::char_separator<char>>::iterator cap_name = tok.begin(); cap_name != tok.end();
167 capabilities.erase(*cap_name);
170 for (
const std::string& capability : capabilities)
175 MoveGroupCapabilityPtr cap = capability_plugin_loader_->createUniqueInstance(capability);
176 cap->setContext(context_);
178 capabilities_.push_back(cap);
180 catch (pluginlib::PluginlibException& ex)
182 RCLCPP_ERROR_STREAM(LOGGER,
183 "Exception while loading move_group capability '" << capability <<
"': " << ex.what());
187 std::stringstream ss;
190 ss <<
"********************************************************" <<
'\n';
191 ss <<
"* MoveGroup using: " <<
'\n';
192 for (
const MoveGroupCapabilityPtr& cap : capabilities_)
193 ss <<
"* - " << cap->getName() <<
'\n';
194 ss <<
"********************************************************" <<
'\n';
195 RCLCPP_INFO(LOGGER,
"%s", ss.str().c_str());
198 MoveGroupContextPtr context_;
199 std::shared_ptr<pluginlib::ClassLoader<MoveGroupCapability>> capability_plugin_loader_;
200 std::vector<MoveGroupCapabilityPtr> capabilities_;
204 int main(
int argc,
char** argv)
206 rclcpp::init(argc, argv);
208 rclcpp::NodeOptions
opt;
209 opt.allow_undeclared_parameters(
true);
210 opt.automatically_declare_parameters_from_overrides(
true);
211 rclcpp::Node::SharedPtr nh = rclcpp::Node::make_shared(
"move_group",
opt);
216 std::vector<std::string> planning_pipeline_configs;
217 if (nh->get_parameter(
"planning_pipelines", planning_pipeline_configs))
219 if (planning_pipeline_configs.empty())
221 RCLCPP_ERROR(LOGGER,
"Failed to read parameter 'move_group.planning_pipelines'");
225 for (
const auto& config : planning_pipeline_configs)
234 std::string default_planning_pipeline;
235 if (nh->get_parameter(
"default_planning_pipeline", default_planning_pipeline))
238 if (std::find(pipeline_names.begin(), pipeline_names.end(), default_planning_pipeline) == pipeline_names.end())
241 "MoveGroup launched with ~default_planning_pipeline '%s' not configured in ~planning_pipelines",
242 default_planning_pipeline.c_str());
243 default_planning_pipeline =
"";
246 else if (pipeline_names.size() > 1)
250 "MoveGroup launched without ~default_planning_pipeline specifying the namespace for the default "
251 "planning pipeline configuration");
255 if (default_planning_pipeline.empty())
257 if (!pipeline_names.empty())
259 RCLCPP_WARN(LOGGER,
"Using default pipeline '%s'", pipeline_names[0].c_str());
260 default_planning_pipeline = pipeline_names[0];
264 RCLCPP_WARN(LOGGER,
"Falling back to using the the move_group node namespace (deprecated behavior).");
265 default_planning_pipeline =
"move_group";
271 nh->set_parameter(rclcpp::Parameter(
"default_planning_pipeline", default_planning_pipeline));
275 const auto tf_buffer = std::make_shared<tf2_ros::Buffer>(nh->get_clock(), tf2::durationFromSec(10.0));
276 const auto moveit_cpp = std::make_shared<moveit_cpp::MoveItCpp>(nh, moveit_cpp_options, tf_buffer);
282 for (
int i = 1; i < argc; ++i)
283 if (strncmp(argv[i],
"--debug", 7) == 0)
290 RCLCPP_INFO(LOGGER,
"MoveGroup debug mode is ON");
292 RCLCPP_INFO(LOGGER,
"MoveGroup debug mode is OFF");
294 rclcpp::executors::MultiThreadedExecutor executor;
298 bool monitor_dynamics;
299 if (nh->get_parameter(
"monitor_dynamics", monitor_dynamics) && monitor_dynamics)
301 RCLCPP_INFO(LOGGER,
"MoveGroup monitors robot dynamics (higher load)");
308 executor.add_node(nh);
314 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)
const rclcpp::Logger LOGGER
Parameter container for initializing MoveItCpp.
PlanningPipelineOptions planning_pipeline_options
std::vector< std::string > pipeline_names
std::string parent_namespace