moveit2
The MoveIt Motion Planning Framework for ROS 2.
servo_ros_integration.test.py
Go to the documentation of this file.
1 import os
2 import launch
3 import unittest
4 import launch_ros
5 import launch_testing
6 from ament_index_python.packages import get_package_share_directory
7 from moveit_configs_utils import MoveItConfigsBuilder
8 from launch_param_builder import ParameterBuilder
9 from launch.conditions import IfCondition, UnlessCondition
10 from launch.substitutions import LaunchConfiguration
11 
12 
14  moveit_config = (
15  MoveItConfigsBuilder("moveit_resources_panda")
16  .robot_description(file_path="config/panda.urdf.xacro")
17  .to_moveit_configs()
18  )
19 
20  # Launch Servo as a standalone node or as a "node component" for better latency/efficiency
21  launch_as_standalone_node = LaunchConfiguration(
22  "launch_as_standalone_node", default="true"
23  )
24 
25  # Get parameters for the Servo node
26  servo_params = {
27  "moveit_servo": ParameterBuilder("moveit_servo")
28  .yaml("config/test_config_panda.yaml")
29  .to_dict()
30  }
31 
32  # This filter parameter should be >1. Increase it for greater smoothing but slower motion.
33  low_pass_filter_coeff = {"butterworth_filter_coeff": 1.5}
34 
35  # ros2_control using FakeSystem as hardware
36  ros2_controllers_path = os.path.join(
37  get_package_share_directory("moveit_resources_panda_moveit_config"),
38  "config",
39  "ros2_controllers.yaml",
40  )
41  ros2_control_node = launch_ros.actions.Node(
42  package="controller_manager",
43  executable="ros2_control_node",
44  parameters=[ros2_controllers_path],
45  remappings=[
46  ("/controller_manager/robot_description", "/robot_description"),
47  ],
48  output="screen",
49  )
50 
51  joint_state_broadcaster_spawner = launch_ros.actions.Node(
52  package="controller_manager",
53  executable="spawner",
54  arguments=[
55  "joint_state_broadcaster",
56  "--controller-manager-timeout",
57  "300",
58  "--controller-manager",
59  "/controller_manager",
60  ],
61  output="screen",
62  )
63 
64  panda_arm_controller_spawner = launch_ros.actions.Node(
65  package="controller_manager",
66  executable="spawner",
67  arguments=["panda_arm_controller", "-c", "/controller_manager"],
68  )
69 
70  # Launch as much as possible in components
71  container = launch_ros.actions.ComposableNodeContainer(
72  name="moveit_servo_demo_container",
73  namespace="/",
74  package="rclcpp_components",
75  executable="component_container_mt",
76  composable_node_descriptions=[
77  # Example of launching Servo as a node component
78  # Launching as a node component makes ROS 2 intraprocess communication more efficient.
79  launch_ros.descriptions.ComposableNode(
80  package="moveit_servo",
81  plugin="moveit_servo::ServoNode",
82  name="servo_node",
83  parameters=[
84  servo_params,
85  low_pass_filter_coeff,
86  moveit_config.robot_description,
87  moveit_config.robot_description_semantic,
88  moveit_config.robot_description_kinematics,
89  ],
90  condition=UnlessCondition(launch_as_standalone_node),
91  ),
92  launch_ros.descriptions.ComposableNode(
93  package="robot_state_publisher",
94  plugin="robot_state_publisher::RobotStatePublisher",
95  name="robot_state_publisher",
96  parameters=[moveit_config.robot_description],
97  ),
98  launch_ros.descriptions.ComposableNode(
99  package="tf2_ros",
100  plugin="tf2_ros::StaticTransformBroadcasterNode",
101  name="static_tf2_broadcaster",
102  parameters=[{"child_frame_id": "/panda_link0", "frame_id": "/world"}],
103  ),
104  ],
105  output="screen",
106  )
107  # Launch a standalone Servo node.
108  # As opposed to a node component, this may be necessary (for example) if Servo is running on a different PC
109  servo_node = launch_ros.actions.Node(
110  package="moveit_servo",
111  executable="servo_node",
112  name="servo_node",
113  parameters=[
114  servo_params,
115  low_pass_filter_coeff,
116  moveit_config.robot_description,
117  moveit_config.robot_description_semantic,
118  moveit_config.robot_description_kinematics,
119  ],
120  output="screen",
121  condition=IfCondition(launch_as_standalone_node),
122  )
123 
124  servo_gtest = launch_ros.actions.Node(
125  executable=launch.substitutions.PathJoinSubstitution(
126  [
127  launch.substitutions.LaunchConfiguration("test_binary_dir"),
128  "moveit_servo_ros_integration_test",
129  ]
130  ),
131  output="screen",
132  )
133 
134  return launch.LaunchDescription(
135  [
136  servo_node,
137  container,
138  launch.actions.TimerAction(period=3.0, actions=[ros2_control_node]),
139  launch.actions.TimerAction(
140  period=5.0, actions=[joint_state_broadcaster_spawner]
141  ),
142  launch.actions.TimerAction(
143  period=7.0, actions=[panda_arm_controller_spawner]
144  ),
145  launch.actions.TimerAction(period=9.0, actions=[servo_gtest]),
146  launch_testing.actions.ReadyToTest(),
147  ]
148  ), {
149  "servo_gtest": servo_gtest,
150  }
151 
152 
153 class TestGTestWaitForCompletion(unittest.TestCase):
154  # Waits for test to complete, then waits a bit to make sure result files are generated
155  def test_gtest_run_complete(self, servo_gtest):
156  self.proc_info.assertWaitForShutdown(servo_gtest, timeout=4000.0)
157 
158 
159 @launch_testing.post_shutdown_test()
160 class TestGTestProcessPostShutdown(unittest.TestCase):
161  # Checks if the test has been completed with acceptable exit codes (successful codes)
162  def test_gtest_pass(self, proc_info, servo_gtest):
163  launch_testing.asserts.assertExitCodes(proc_info, process=servo_gtest)