Skip to content

Commit 378045d

Browse files
committed
Add tutorial for simultaneous trajectory execution
1 parent c9b1963 commit 378045d

6 files changed

+150
-0
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,4 @@ add_subdirectory(doc/collision_environments)
7474
add_subdirectory(doc/visualizing_collisions)
7575
add_subdirectory(doc/bullet_collision_checker)
7676
add_subdirectory(doc/mesh_filter)
77+
add_subdirectory(doc/simultaneous_trajectory_execution)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
add_executable(simultaneous_trajectory_execution_tutorial src/simultaneous_trajectory_execution_tutorial.cpp)
2+
target_link_libraries(simultaneous_trajectory_execution_tutorial ${catkin_LIBRARIES} ${Boost_LIBRARIES})
3+
install(TARGETS simultaneous_trajectory_execution_tutorial DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
4+
5+
install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<launch>
2+
3+
<node name="simultaneous_trajectory_execution_tutorial"
4+
pkg="moveit_tutorials"
5+
type="simultaneous_trajectory_execution_tutorial"
6+
respawn="false"
7+
output="screen">
8+
</node>
9+
10+
</launch>
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Simultaneous Trajectory Execution
2+
==================================
3+
4+
Introduction
5+
------------
6+
MoveIt now allows simultaneous execution of trajectories, as long as, each trajectory uses a different set of controllers. For example, in a dual arm environment, each arm can execute a different set of trajectories without needing to wait for the other arm to finish moving or manually synchronizing the motion of both arm into a single trajectory. Optionally, a collision check is performed right before execution of new trajectories to prevent collisions with active trajectories.
7+
8+
9+
.. only:: html
10+
11+
.. figure:: simultaneous-execution-rviz.gif
12+
13+
Simultaneous execution of several trajectories through Rviz plugin.
14+
15+
16+
Getting Started
17+
---------------
18+
If you haven't already done so, make sure you've completed the steps in `Getting Started <../getting_started/getting_started.html>`_.
19+
20+
Setup
21+
---------------
22+
The simultaneous trajectory execution feature can be enabled or disabled through the dynamic reconfigure parameter `/move_group/trajectory_execution/enable_simultaneous_execution`.
23+
Optionally, an extra layer of collision checking, done right before execution of trajectories, can be enabled through the dynamic reconfigure parameter `/move_group/trajectory_execution/enable_collision_checking`.
24+
25+
Running the code
26+
----------------
27+
Open two shells. In the first shell start RViz and wait for everything to finish loading: ::
28+
29+
roslaunch moveit_resources_dual_panda_moveit_config demo.launch
30+
31+
In the second shell, run the launch file for this demo: ::
32+
33+
roslaunch moveit_tutorials simultaneous_trajectory_execution_tutorial.launch
34+
35+
Expected Output
36+
---------------
37+
Though, two independent trajectories for two different joint groups have been planned, both can be simultaneously executed.
38+
39+
The entire code
40+
---------------
41+
The entire code can be seen :codedir:`here in the MoveIt GitHub project<simultaneous_trajectory_execution>`.
42+
43+
.. tutorial-formatter:: ./src/simultaneous_trajectory_execution_tutorial.cpp
44+
45+
The launch file
46+
---------------
47+
The entire launch file is :codedir:`here <simultaneous_trajectory_execution/launch/simultaneous_trajectory_execution_tutorial.launch>` on GitHub. All the code in this tutorial can be compiled and run from the moveit_tutorials package.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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

Comments
 (0)