72 auto param_listener = local_planner_parameters::ParamListener(node_,
"");
73 config_ = std::make_shared<local_planner_parameters::Params>(param_listener.get_params());
76 if (config_->local_solution_topic_type ==
"std_msgs/Float64MultiArray")
78 if ((config_->publish_joint_positions && config_->publish_joint_velocities) ||
79 (!config_->publish_joint_positions && !config_->publish_joint_velocities))
81 RCLCPP_ERROR(node_->get_logger(),
82 "When publishing a std_msgs/Float64MultiArray, you must select positions OR velocities. "
83 "Enabling both or none is not possible!");
89 planning_scene_monitor_ = std::make_shared<planning_scene_monitor::PlanningSceneMonitor>(
90 node_,
"robot_description",
"local_planner/planning_scene_monitor");
91 if (!planning_scene_monitor_->getPlanningScene())
93 RCLCPP_ERROR(node_->get_logger(),
"Unable to configure planning scene monitor");
98 planning_scene_monitor_->startSceneMonitor(config_->monitored_planning_scene_topic);
99 planning_scene_monitor_->startWorldGeometryMonitor(config_->collision_object_topic);
100 planning_scene_monitor_->startStateMonitor(config_->joint_states_topic,
"/attached_collision_object");
101 planning_scene_monitor_->monitorDiffs(
true);
102 planning_scene_monitor_->stopPublishingPlanningScene();
107 trajectory_operator_loader_ = std::make_unique<pluginlib::ClassLoader<TrajectoryOperatorInterface>>(
108 "moveit_hybrid_planning",
"moveit::hybrid_planning::TrajectoryOperatorInterface");
110 catch (pluginlib::PluginlibException& ex)
112 RCLCPP_ERROR(node_->get_logger(),
"Exception while creating trajectory operator plugin loader: '%s'", ex.what());
117 trajectory_operator_instance_ =
118 trajectory_operator_loader_->createUniqueInstance(config_->trajectory_operator_plugin_name);
119 if (!trajectory_operator_instance_->initialize(node_, planning_scene_monitor_->getRobotModel(),
120 config_->group_name))
121 throw std::runtime_error(
"Unable to initialize trajectory operator plugin");
122 RCLCPP_INFO(node_->get_logger(),
"Using trajectory operator interface '%s'",
123 config_->trajectory_operator_plugin_name.c_str());
125 catch (pluginlib::PluginlibException& ex)
127 RCLCPP_ERROR(node_->get_logger(),
"Exception while loading trajectory operator '%s': '%s'",
128 config_->trajectory_operator_plugin_name.c_str(), ex.what());
135 local_constraint_solver_plugin_loader_ = std::make_unique<pluginlib::ClassLoader<LocalConstraintSolverInterface>>(
136 "moveit_hybrid_planning",
"moveit::hybrid_planning::LocalConstraintSolverInterface");
138 catch (pluginlib::PluginlibException& ex)
140 RCLCPP_ERROR(node_->get_logger(),
"Exception while creating constraint solver plugin loader '%s'", ex.what());
145 local_constraint_solver_instance_ =
146 local_constraint_solver_plugin_loader_->createUniqueInstance(config_->local_constraint_solver_plugin_name);
147 if (!local_constraint_solver_instance_->initialize(node_, planning_scene_monitor_, config_->group_name))
148 throw std::runtime_error(
"Unable to initialize constraint solver plugin");
149 RCLCPP_INFO(node_->get_logger(),
"Using constraint solver interface '%s'",
150 config_->local_constraint_solver_plugin_name.c_str());
152 catch (pluginlib::PluginlibException& ex)
154 RCLCPP_ERROR(node_->get_logger(),
"Exception while loading constraint solver '%s': '%s'",
155 config_->local_constraint_solver_plugin_name.c_str(), ex.what());
160 cb_group_ = node_->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
161 local_planning_request_server_ = rclcpp_action::create_server<moveit_msgs::action::LocalPlanner>(
162 node_,
"local_planning_action",
164 [
this](
const rclcpp_action::GoalUUID& ,
165 const std::shared_ptr<const moveit_msgs::action::LocalPlanner::Goal>& ) {
166 RCLCPP_INFO(node_->get_logger(),
"Received local planning goal request");
168 if (long_callback_thread_.joinable())
171 auto future = std::async(std::launch::async, &std::thread::join, &long_callback_thread_);
172 if (future.wait_for(JOIN_THREAD_TIMEOUT) == std::future_status::timeout)
174 RCLCPP_WARN(node_->get_logger(),
"Another goal was running. Rejecting the new hybrid planning goal.");
175 return rclcpp_action::GoalResponse::REJECT;
178 return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
181 [
this](
const std::shared_ptr<rclcpp_action::ServerGoalHandle<moveit_msgs::action::LocalPlanner>>& ) {
182 RCLCPP_INFO(node_->get_logger(),
"Received request to cancel local planning goal");
184 if (long_callback_thread_.joinable())
186 long_callback_thread_.join();
188 return rclcpp_action::CancelResponse::ACCEPT;
191 [
this](std::shared_ptr<rclcpp_action::ServerGoalHandle<moveit_msgs::action::LocalPlanner>> goal_handle) {
192 local_planning_goal_handle_ = std::move(goal_handle);
194 if (long_callback_thread_.joinable())
196 long_callback_thread_.join();
200 auto local_planner_timer = [&]() {
202 node_->create_wall_timer(1s / config_->local_planning_frequency, [
this]() {
return executeIteration(); });
204 long_callback_thread_ = std::thread(local_planner_timer);
206 rcl_action_server_get_default_options(), cb_group_);
209 global_solution_subscriber_ = node_->create_subscription<moveit_msgs::msg::MotionPlanResponse>(
210 config_->global_solution_topic, rclcpp::SystemDefaultsQoS(),
211 [
this](
const moveit_msgs::msg::MotionPlanResponse::ConstSharedPtr& msg) {
217 *local_planner_feedback_ = trajectory_operator_instance_->addTrajectorySegment(new_trajectory);
221 if (!local_planner_feedback_->feedback.empty())
223 local_planning_goal_handle_->publish_feedback(local_planner_feedback_);
231 RCLCPP_INFO(node_->get_logger(),
"Using '%s' as local solution topic type",
232 config_->local_solution_topic_type.c_str());
233 if (config_->local_solution_topic_type ==
"trajectory_msgs/JointTrajectory")
235 local_trajectory_publisher_ =
236 node_->create_publisher<trajectory_msgs::msg::JointTrajectory>(config_->local_solution_topic, 1);
238 else if (config_->local_solution_topic_type ==
"std_msgs/Float64MultiArray")
240 local_solution_publisher_ =
241 node_->create_publisher<std_msgs::msg::Float64MultiArray>(config_->local_solution_topic, 1);
243 else if (config_->local_solution_topic_type ==
"CUSTOM")
254 auto result = std::make_shared<moveit_msgs::action::LocalPlanner::Result>();
266 result->error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
267 result->error_message =
"Local planner is in an aborted state. Resetting.";
268 local_planning_goal_handle_->abort(result);
278 return ls->getCurrentState();
282 if (trajectory_operator_instance_->getTrajectoryProgress(current_robot_state) > PROGRESS_THRESHOLD)
284 local_planning_goal_handle_->succeed(result);
292 *local_planner_feedback_ =
293 trajectory_operator_instance_->getLocalTrajectory(current_robot_state, local_trajectory);
297 if (!local_planner_feedback_->feedback.empty())
299 local_planning_goal_handle_->publish_feedback(local_planner_feedback_);
300 RCLCPP_ERROR(node_->get_logger(),
"Local planner somehow failed");
306 trajectory_msgs::msg::JointTrajectory local_solution;
310 *local_planner_feedback_ = local_constraint_solver_instance_->solve(
311 local_trajectory, local_planning_goal_handle_->get_goal(), local_solution);
314 if (!local_planner_feedback_->feedback.empty())
316 local_planning_goal_handle_->publish_feedback(local_planner_feedback_);
324 if (config_->local_solution_topic_type ==
"trajectory_msgs/JointTrajectory")
326 local_trajectory_publisher_->publish(local_solution);
328 else if (config_->local_solution_topic_type ==
"std_msgs/Float64MultiArray")
331 auto joints = std::make_unique<std_msgs::msg::Float64MultiArray>();
332 if (!local_solution.points.empty())
334 if (config_->publish_joint_positions)
336 joints->data = local_solution.points[0].positions;
338 else if (config_->publish_joint_velocities)
340 joints->data = local_solution.points[0].velocities;
343 local_solution_publisher_->publish(std::move(joints));
345 else if (config_->local_solution_topic_type ==
"CUSTOM")
353 result->error_code.val = moveit_msgs::msg::MoveItErrorCodes::FAILURE;
354 result->error_message =
"Unexpected failure.";
355 local_planning_goal_handle_->abort(result);
356 RCLCPP_ERROR(node_->get_logger(),
357 "Local planner somehow failed");