Skip to content

Commit 931343a

Browse files
Add cart-pole demo (#289) (#291)
(cherry picked from commit 27af210) Co-authored-by: Christoph Fröhlich <[email protected]>
1 parent 0c2d0dd commit 931343a

5 files changed

+457
-11
lines changed

doc/index.rst

+49-11
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ This is a ROS 2 package for integrating the *ros2_control* controller architectu
1010

1111
This package provides a Gazebo-Sim system plugin which instantiates a *ros2_control* controller manager and connects it to a Gazebo model.
1212

13-
.. image:: img/gz_ros2_control.gif
14-
:alt: Cart
15-
16-
.. image:: img/diff_drive.gif
17-
:alt: DiffBot
18-
1913
Usage
2014
======
2115

@@ -217,7 +211,15 @@ The following is a basic configuration of the controllers:
217211
gz_ros2_control_demos
218212
==========================================
219213

220-
There are some examples in the *gz_ros2_control_demos* package. These examples allow to launch a cart in a 30 meter rail.
214+
There are some examples in the *gz_ros2_control_demos* package.
215+
216+
Cart on rail
217+
-----------------------------------------------------------
218+
219+
These examples allow to launch a cart in a 30 meter rail.
220+
221+
.. image:: img/gz_ros2_control.gif
222+
:alt: Cart
221223

222224
You can run some of the example configurations by running the following commands:
223225

@@ -226,8 +228,6 @@ You can run some of the example configurations by running the following commands
226228
ros2 launch gz_ros2_control_demos cart_example_position.launch.py
227229
ros2 launch gz_ros2_control_demos cart_example_velocity.launch.py
228230
ros2 launch gz_ros2_control_demos cart_example_effort.launch.py
229-
ros2 launch gz_ros2_control_demos diff_drive_example.launch.py
230-
ros2 launch gz_ros2_control_demos tricycle_drive_example.launch.py
231231
232232
When the Gazebo world is launched, you can run some of the following commands to move the cart.
233233

@@ -236,10 +236,31 @@ When the Gazebo world is launched, you can run some of the following commands to
236236
ros2 run gz_ros2_control_demos example_position
237237
ros2 run gz_ros2_control_demos example_velocity
238238
ros2 run gz_ros2_control_demos example_effort
239+
240+
Mobile robots
241+
-----------------------------------------------------------
242+
243+
.. image:: img/diff_drive.gif
244+
:alt: DiffBot
245+
246+
You can run some of the mobile robots running the following commands:
247+
248+
.. code-block:: shell
249+
250+
ros2 launch gz_ros2_control_demos diff_drive_example.launch.py
251+
ros2 launch gz_ros2_control_demos tricycle_drive_example.launch.py
252+
253+
When the Gazebo world is launched you can run some of the following commands to move the robots.
254+
255+
.. code-block:: shell
256+
239257
ros2 run gz_ros2_control_demos example_diff_drive
240258
ros2 run gz_ros2_control_demos example_tricycle_drive
241259
242-
The following example shows parallel gripper with mimic joint:
260+
Gripper
261+
-----------------------------------------------------------
262+
263+
The following example shows a parallel gripper with a mimic joint:
243264

244265
.. code-block:: shell
245266
@@ -248,7 +269,24 @@ The following example shows parallel gripper with mimic joint:
248269
249270
Send example commands:
250271

251-
252272
.. code-block:: shell
253273
254274
ros2 run gz_ros2_control_demos example_gripper
275+
276+
277+
Pendulum with passive joints (cart-pole)
278+
-----------------------------------------------------------
279+
280+
The following example shows a cart with a pendulum arm:
281+
282+
.. code-block:: shell
283+
284+
ros2 launch gz_ros2_control_demos pendulum_example_effort.launch.py
285+
ros2 run gz_ros2_control_demos example_effort
286+
287+
This uses the effort command interface for the cart's degree of freedom on the rail. To demonstrate that the physics of the passive joint of the pendulum is solved correctly even with the position command interface, run
288+
289+
.. code-block:: shell
290+
291+
ros2 launch gz_ros2_control_demos pendulum_example_position.launch.py
292+
ros2 run gz_ros2_control_demos example_position
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright 2024 ros2_control Development Team
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from launch import LaunchDescription
16+
from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription
17+
from launch.actions import RegisterEventHandler
18+
from launch.event_handlers import OnProcessExit
19+
from launch.launch_description_sources import PythonLaunchDescriptionSource
20+
from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution
21+
22+
from launch_ros.actions import Node
23+
from launch_ros.substitutions import FindPackageShare
24+
25+
26+
def generate_launch_description():
27+
# Launch Arguments
28+
use_sim_time = LaunchConfiguration('use_sim_time', default=True)
29+
30+
# Get URDF via xacro
31+
robot_description_content = Command(
32+
[
33+
PathJoinSubstitution([FindExecutable(name="xacro")]),
34+
" ",
35+
PathJoinSubstitution(
36+
[FindPackageShare("gz_ros2_control_demos"),
37+
"urdf", "test_pendulum_effort.xacro.urdf"]
38+
),
39+
]
40+
)
41+
robot_description = {"robot_description": robot_description_content}
42+
43+
node_robot_state_publisher = Node(
44+
package='robot_state_publisher',
45+
executable='robot_state_publisher',
46+
output='screen',
47+
parameters=[robot_description]
48+
)
49+
50+
gz_spawn_entity = Node(
51+
package='ros_gz_sim',
52+
executable='create',
53+
output='screen',
54+
arguments=["-topic", "robot_description",
55+
"-name", "cart", "-allow_renaming", "true"],
56+
)
57+
58+
load_joint_state_broadcaster = ExecuteProcess(
59+
cmd=['ros2', 'control', 'load_controller', '--set-state', 'active',
60+
'joint_state_broadcaster'],
61+
output='screen'
62+
)
63+
64+
load_joint_effort_controller = ExecuteProcess(
65+
cmd=['ros2', 'control', 'load_controller',
66+
'--set-state', 'active', 'effort_controller'],
67+
output='screen'
68+
)
69+
70+
return LaunchDescription([
71+
# Launch gazebo environment
72+
IncludeLaunchDescription(
73+
PythonLaunchDescriptionSource(
74+
[PathJoinSubstitution([FindPackageShare('ros_gz_sim'),
75+
'launch',
76+
'gz_sim.launch.py'])]),
77+
launch_arguments=[('gz_args', [' -r -v 3 empty.sdf'])]),
78+
RegisterEventHandler(
79+
event_handler=OnProcessExit(
80+
target_action=gz_spawn_entity,
81+
on_exit=[load_joint_state_broadcaster],
82+
)
83+
),
84+
RegisterEventHandler(
85+
event_handler=OnProcessExit(
86+
target_action=load_joint_state_broadcaster,
87+
on_exit=[load_joint_effort_controller],
88+
)
89+
),
90+
node_robot_state_publisher,
91+
gz_spawn_entity,
92+
# Launch Arguments
93+
DeclareLaunchArgument(
94+
'use_sim_time',
95+
default_value=use_sim_time,
96+
description='If true, use simulated clock'),
97+
])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright 2024 ros2_control Development Team
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from launch import LaunchDescription
16+
from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription
17+
from launch.actions import RegisterEventHandler
18+
from launch.event_handlers import OnProcessExit
19+
from launch.launch_description_sources import PythonLaunchDescriptionSource
20+
from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution
21+
22+
from launch_ros.actions import Node
23+
from launch_ros.substitutions import FindPackageShare
24+
25+
26+
def generate_launch_description():
27+
# Launch Arguments
28+
use_sim_time = LaunchConfiguration('use_sim_time', default=True)
29+
30+
# Get URDF via xacro
31+
robot_description_content = Command(
32+
[
33+
PathJoinSubstitution([FindExecutable(name="xacro")]),
34+
" ",
35+
PathJoinSubstitution(
36+
[FindPackageShare("gz_ros2_control_demos"),
37+
"urdf", "test_pendulum_position.xacro.urdf"]
38+
),
39+
]
40+
)
41+
robot_description = {"robot_description": robot_description_content}
42+
43+
node_robot_state_publisher = Node(
44+
package='robot_state_publisher',
45+
executable='robot_state_publisher',
46+
output='screen',
47+
parameters=[robot_description]
48+
)
49+
50+
gz_spawn_entity = Node(
51+
package='ros_gz_sim',
52+
executable='create',
53+
output='screen',
54+
arguments=["-topic", "robot_description",
55+
"-name", "cart", "-allow_renaming", "true"],
56+
)
57+
58+
load_joint_state_broadcaster = ExecuteProcess(
59+
cmd=['ros2', 'control', 'load_controller', '--set-state', 'active',
60+
'joint_state_broadcaster'],
61+
output='screen'
62+
)
63+
64+
load_joint_trajectory_controller = ExecuteProcess(
65+
cmd=['ros2', 'control', 'load_controller', '--set-state', 'active',
66+
'joint_trajectory_controller'],
67+
output='screen'
68+
)
69+
70+
return LaunchDescription([
71+
# Launch gazebo environment
72+
IncludeLaunchDescription(
73+
PythonLaunchDescriptionSource(
74+
[PathJoinSubstitution([FindPackageShare('ros_gz_sim'),
75+
'launch',
76+
'gz_sim.launch.py'])]),
77+
launch_arguments=[('gz_args', [' -r -v 4 empty.sdf'])]),
78+
RegisterEventHandler(
79+
event_handler=OnProcessExit(
80+
target_action=gz_spawn_entity,
81+
on_exit=[load_joint_state_broadcaster],
82+
)
83+
),
84+
RegisterEventHandler(
85+
event_handler=OnProcessExit(
86+
target_action=load_joint_state_broadcaster,
87+
on_exit=[load_joint_trajectory_controller],
88+
)
89+
),
90+
node_robot_state_publisher,
91+
gz_spawn_entity,
92+
# Launch Arguments
93+
DeclareLaunchArgument(
94+
'use_sim_time',
95+
default_value=use_sim_time,
96+
description='If true, use simulated clock'),
97+
])

0 commit comments

Comments
 (0)