47 #include <moveit_msgs/action/hybrid_planner.hpp>
48 #include <moveit_msgs/msg/display_robot_state.hpp>
49 #include <moveit_msgs/msg/motion_plan_response.hpp>
50 #include <rclcpp/executors.hpp>
51 #include <rclcpp/experimental/buffers/intra_process_buffer.hpp>
52 #include <rclcpp/logger.hpp>
53 #include <rclcpp/logging.hpp>
54 #include <rclcpp/node.hpp>
55 #include <rclcpp/node_options.hpp>
56 #include <rclcpp/parameter_value.hpp>
57 #include <rclcpp/qos.hpp>
58 #include <rclcpp/qos_event.hpp>
59 #include <rclcpp/subscription.hpp>
60 #include <rclcpp/timer.hpp>
61 #include <rclcpp/utilities.hpp>
62 #include <rclcpp_action/client.hpp>
63 #include <rclcpp_action/client_goal_handle.hpp>
64 #include <rclcpp_action/create_client.hpp>
66 using namespace std::chrono_literals;
69 const rclcpp::Logger
LOGGER = rclcpp::get_logger(
"test_hybrid_planning_client");
79 std::string hybrid_planning_action_name =
"";
80 if (node_->has_parameter(
"hybrid_planning_action_name"))
82 node_->get_parameter<std::string>(
"hybrid_planning_action_name", hybrid_planning_action_name);
86 RCLCPP_ERROR(LOGGER,
"hybrid_planning_action_name parameter was not defined");
87 std::exit(EXIT_FAILURE);
90 rclcpp_action::create_client<moveit_msgs::action::HybridPlanner>(node_, hybrid_planning_action_name);
92 collision_object_1_.header.frame_id =
"panda_link0";
93 collision_object_1_.id =
"box1";
95 collision_object_2_.header.frame_id =
"panda_link0";
96 collision_object_2_.id =
"box2";
98 collision_object_3_.header.frame_id =
"panda_link0";
99 collision_object_3_.id =
"box3";
101 box_1_.type = box_1_.BOX;
102 box_1_.dimensions = { 0.5, 0.8, 0.01 };
104 box_2_.type = box_2_.BOX;
105 box_2_.dimensions = { 1.0, 0.4, 0.01 };
108 global_solution_subscriber_ = node_->create_subscription<moveit_msgs::msg::MotionPlanResponse>(
109 "global_trajectory", rclcpp::SystemDefaultsQoS(),
110 [
this](
const moveit_msgs::msg::MotionPlanResponse::ConstSharedPtr& ) {
112 collision_object_1_.operation = collision_object_1_.REMOVE;
115 geometry_msgs::msg::Pose box_pose_2;
116 box_pose_2.position.x = 0.2;
117 box_pose_2.position.y = 0.4;
118 box_pose_2.position.z = 0.95;
120 collision_object_2_.primitives.push_back(box_2_);
121 collision_object_2_.primitive_poses.push_back(box_pose_2);
122 collision_object_2_.operation = collision_object_2_.ADD;
124 geometry_msgs::msg::Pose box_pose_3;
125 box_pose_3.position.x = 0.2;
126 box_pose_3.position.y = -0.4;
127 box_pose_3.position.z = 0.95;
129 collision_object_3_.primitives.push_back(box_2_);
130 collision_object_3_.primitive_poses.push_back(box_pose_3);
131 collision_object_3_.operation = collision_object_3_.ADD;
136 scene->processCollisionObjectMsg(collision_object_2_);
137 scene->processCollisionObjectMsg(collision_object_3_);
138 scene->processCollisionObjectMsg(collision_object_1_);
145 RCLCPP_INFO(LOGGER,
"Initialize Planning Scene Monitor");
146 tf_buffer_ = std::make_shared<tf2_ros::Buffer>(node_->get_clock());
148 planning_scene_monitor_ = std::make_shared<planning_scene_monitor::PlanningSceneMonitor>(
149 node_,
"robot_description", tf_buffer_,
"planning_scene_monitor");
150 if (!planning_scene_monitor_->getPlanningScene())
152 RCLCPP_ERROR(LOGGER,
"The planning scene was not retrieved!");
157 planning_scene_monitor_->startStateMonitor();
158 planning_scene_monitor_->providePlanningSceneService();
159 planning_scene_monitor_->setPlanningScenePublishingFrequency(100);
162 planning_scene_monitor_->startSceneMonitor();
165 if (!planning_scene_monitor_->waitForCurrentRobotState(node_->now(), 5))
167 RCLCPP_ERROR(LOGGER,
"Timeout when waiting for /joint_states updates. Is the robot running?");
171 if (!hp_action_client_->wait_for_action_server(20s))
173 RCLCPP_ERROR(LOGGER,
"Hybrid planning action server not available after waiting");
177 geometry_msgs::msg::Pose box_pose;
178 box_pose.position.x = 0.4;
179 box_pose.position.y = 0.0;
180 box_pose.position.z = 0.85;
182 collision_object_1_.primitives.push_back(box_1_);
183 collision_object_1_.primitive_poses.push_back(box_pose);
184 collision_object_1_.operation = collision_object_1_.ADD;
189 scene->processCollisionObjectMsg(collision_object_1_);
192 RCLCPP_INFO(LOGGER,
"Wait 2s for the collision object");
193 rclcpp::sleep_for(2s);
196 const std::string planning_group =
"panda_arm";
201 const auto robot_state = std::make_shared<moveit::core::RobotState>(robot_model);
205 robot_state->setToDefaultValues(joint_model_group,
"ready");
206 robot_state->update();
210 locked_planning_scene->setCurrentState(*robot_state);
217 goal_motion_request.group_name = planning_group;
218 goal_motion_request.num_planning_attempts = 10;
219 goal_motion_request.max_velocity_scaling_factor = 0.1;
220 goal_motion_request.max_acceleration_scaling_factor = 0.1;
221 goal_motion_request.allowed_planning_time = 2.0;
222 goal_motion_request.planner_id =
"ompl";
223 goal_motion_request.pipeline_id =
"ompl";
226 std::vector<double> joint_values = { 0.0, 0.0, 0.0, 0.0, 0.0, 1.571, 0.785 };
229 goal_motion_request.goal_constraints.resize(1);
230 goal_motion_request.goal_constraints[0] =
234 moveit_msgs::msg::MotionSequenceItem sequence_item;
235 sequence_item.req = goal_motion_request;
236 sequence_item.blend_radius = 0.0;
238 moveit_msgs::msg::MotionSequenceRequest sequence_request;
239 sequence_request.items.push_back(sequence_item);
241 auto goal_action_request = moveit_msgs::action::HybridPlanner::Goal();
242 goal_action_request.planning_group = planning_group;
243 goal_action_request.motion_sequence = sequence_request;
245 auto send_goal_options = rclcpp_action::Client<moveit_msgs::action::HybridPlanner>::SendGoalOptions();
246 send_goal_options.result_callback =
247 [](
const rclcpp_action::ClientGoalHandle<moveit_msgs::action::HybridPlanner>::WrappedResult& result) {
250 case rclcpp_action::ResultCode::SUCCEEDED:
251 RCLCPP_INFO(LOGGER,
"Hybrid planning goal succeeded");
253 case rclcpp_action::ResultCode::ABORTED:
254 RCLCPP_ERROR(LOGGER,
"Hybrid planning goal was aborted");
256 case rclcpp_action::ResultCode::CANCELED:
257 RCLCPP_ERROR(LOGGER,
"Hybrid planning goal was canceled");
260 RCLCPP_ERROR(LOGGER,
"Unknown hybrid planning result code");
262 RCLCPP_INFO(LOGGER,
"Hybrid planning result received");
265 send_goal_options.feedback_callback =
266 [](
const rclcpp_action::ClientGoalHandle<moveit_msgs::action::HybridPlanner>::SharedPtr& ,
267 const std::shared_ptr<const moveit_msgs::action::HybridPlanner::Feedback>& feedback) {
268 RCLCPP_INFO_STREAM(LOGGER, feedback->feedback);
271 RCLCPP_INFO(LOGGER,
"Sending hybrid planning goal");
273 auto goal_handle_future = hp_action_client_->async_send_goal(goal_action_request, send_goal_options);
277 rclcpp::Node::SharedPtr node_;
278 rclcpp_action::Client<moveit_msgs::action::HybridPlanner>::SharedPtr hp_action_client_;
279 rclcpp::Subscription<moveit_msgs::msg::MotionPlanResponse>::SharedPtr global_solution_subscriber_;
280 planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor_;
281 rclcpp::TimerBase::SharedPtr timer_;
283 moveit_msgs::msg::CollisionObject collision_object_1_;
284 moveit_msgs::msg::CollisionObject collision_object_2_;
285 moveit_msgs::msg::CollisionObject collision_object_3_;
286 shape_msgs::msg::SolidPrimitive box_1_;
287 shape_msgs::msg::SolidPrimitive box_2_;
290 std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
293 int main(
int argc,
char** argv)
295 rclcpp::init(argc, argv);
296 rclcpp::NodeOptions node_options;
297 node_options.automatically_declare_parameters_from_overrides(
true);
299 rclcpp::Node::SharedPtr node = std::make_shared<rclcpp::Node>(
"hybrid_planning_test_node",
"", node_options);
302 std::thread run_demo([&
demo]() {
304 rclcpp::sleep_for(5s);
HybridPlanningDemo(const rclcpp::Node::SharedPtr &node)
Representation of a robot's state. This includes position, velocity, acceleration and effort.
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
This is a convenience class for obtaining access to an instance of a locked PlanningScene.
@ UPDATE_SCENE
The entire scene was updated.
int main(int argc, char **argv)
moveit_msgs::msg::Constraints constructGoalConstraints(const moveit::core::RobotState &state, const moveit::core::JointModelGroup *jmg, double tolerance_below, double tolerance_above)
Generates a constraint message intended to be used as a goal constraint for a joint group....
void robotStateToRobotStateMsg(const RobotState &state, moveit_msgs::msg::RobotState &robot_state, bool copy_attached_bodies=true)
Convert a MoveIt robot state to a robot state message.
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
const rclcpp::Logger LOGGER