|
| 1 | +/* Author: Cristian C. Beltran-Hernandez */ |
| 2 | + |
| 3 | +#include <ros/ros.h> |
| 4 | + |
| 5 | +#include <memory> |
| 6 | + |
| 7 | +#include <geometry_msgs/PointStamped.h> |
| 8 | +#include <moveit/move_group_interface/move_group_interface.h> |
| 9 | +#include <stdlib.h> |
| 10 | + |
| 11 | +int main(int argc, char** argv) |
| 12 | +{ |
| 13 | + ros::init(argc, argv, "simultaneous_trajectory_execution_move_group"); |
| 14 | + |
| 15 | + // ROS spinning must be running for the MoveGroupInterface to get information |
| 16 | + // about the robot's state. One way to do this is to start an AsyncSpinner |
| 17 | + // beforehand. |
| 18 | + ros::AsyncSpinner spinner(1); |
| 19 | + spinner.start(); |
| 20 | + |
| 21 | + // BEGIN_TUTORIAL |
| 22 | + // |
| 23 | + // Setup |
| 24 | + // ^^^^^ |
| 25 | + // Let's start by creating planning groups for each robot arm. |
| 26 | + // The panda dual arm environment has two planning groups defined as `panda_1` and `panda_2` |
| 27 | + moveit::planning_interface::MoveGroupInterface panda_1_group("panda_1"); |
| 28 | + moveit::planning_interface::MoveGroupInterface panda_2_group("panda_2"); |
| 29 | + |
| 30 | + // Now, let's define a target pose for `panda_1` |
| 31 | + geometry_msgs::PoseStamped panda_1_target_pose; |
| 32 | + panda_1_target_pose.header.frame_id = "base"; |
| 33 | + panda_1_target_pose.pose.position.x = 0.450; |
| 34 | + panda_1_target_pose.pose.position.y = -0.50; |
| 35 | + panda_1_target_pose.pose.position.z = 1.600; |
| 36 | + panda_1_target_pose.pose.orientation.x = 0.993436; |
| 37 | + panda_1_target_pose.pose.orientation.y = 3.5161e-05; |
| 38 | + panda_1_target_pose.pose.orientation.z = 0.114386; |
| 39 | + panda_1_target_pose.pose.orientation.w = 2.77577e-05; |
| 40 | + |
| 41 | + // And one for `panda_2` |
| 42 | + geometry_msgs::PoseStamped panda_2_target_pose; |
| 43 | + panda_2_target_pose.header.frame_id = "base"; |
| 44 | + panda_2_target_pose.pose.position.x = 0.450; |
| 45 | + panda_2_target_pose.pose.position.y = 0.40; |
| 46 | + panda_2_target_pose.pose.position.z = 1.600; |
| 47 | + panda_2_target_pose.pose.orientation.x = 0.993434; |
| 48 | + panda_2_target_pose.pose.orientation.y = -7.54803e-06; |
| 49 | + panda_2_target_pose.pose.orientation.z = 0.114403; |
| 50 | + panda_2_target_pose.pose.orientation.w = 3.67256e-05; |
| 51 | + |
| 52 | + // Planning |
| 53 | + // ^^^^^^^^ |
| 54 | + // Let's plan a trajectory for `panda_1` using the previously defined target pose. |
| 55 | + panda_1_group.clearPoseTargets(); |
| 56 | + panda_1_group.setStartStateToCurrentState(); |
| 57 | + panda_1_group.setPoseTarget(panda_1_target_pose); |
| 58 | + |
| 59 | + moveit::planning_interface::MoveGroupInterface::Plan panda_1_plan; |
| 60 | + bool success1 = (panda_1_group.plan(panda_1_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS); |
| 61 | + if (!success1) |
| 62 | + { |
| 63 | + ROS_INFO("Plan with Panda 1 did not succeeded"); |
| 64 | + } |
| 65 | + |
| 66 | + // Same for `panda_2`. |
| 67 | + panda_2_group.clearPoseTargets(); |
| 68 | + panda_2_group.setStartStateToCurrentState(); |
| 69 | + panda_2_group.setPoseTarget(panda_2_target_pose); |
| 70 | + |
| 71 | + moveit::planning_interface::MoveGroupInterface::Plan panda_2_plan; |
| 72 | + bool success2 = (panda_2_group.plan(panda_2_plan) == moveit::planning_interface::MoveItErrorCode::SUCCESS); |
| 73 | + if (!success2) |
| 74 | + { |
| 75 | + ROS_INFO("Plan with Panda 2 did not succeeded"); |
| 76 | + } |
| 77 | + |
| 78 | + // Simultaneous Execution |
| 79 | + // ^^^^^^^^^^^^^^^^^^^^^^ |
| 80 | + // Finally, let's execute both plans asynchronously to have them run simultaneously. |
| 81 | + panda_1_group.asyncExecute(panda_1_plan); |
| 82 | + panda_2_group.asyncExecute(panda_2_plan); |
| 83 | + // END_TUTORIAL |
| 84 | + |
| 85 | + ros::shutdown(); |
| 86 | + return 0; |
| 87 | +} |
0 commit comments