Skip to content

[Example 17] RRBot with Hardware Component that publishes diagnostics #840

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ The following examples are part of this demo repository:

This example shows how to create chained controllers using diff_drive_controller and two pid_controllers to control a differential drive robot.

* Example 17: ["RRBot with Hardware Component that publishes diagnostics"](example_17)

This example shows how to publish diagnostics from a hardware component using the Executor passed from Controller Manager.

## Structure

The repository is structured into `example_XY` folders that fully contained packages with names `ros2_control_demos_example_XY`.
Expand Down
4 changes: 4 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ Example 15: "Using multiple controller managers"
Example 16: "DiffBot with chained controllers"
This example shows how to create chained controllers using diff_drive_controller and pid_controllers to control a differential drive robot.

Example 17: "RRBot with Hardware Component that publishes diagnostics"
This example shows how to publish diagnostics from a hardware component using the Executor passed from Controller Manager.

.. _ros2_control_demos_install:

=====================
Expand Down Expand Up @@ -296,3 +299,4 @@ Examples
Example 14: Modular robots with actuators not providing states <../example_14/doc/userdoc.rst>
Example 15: Using multiple controller managers <../example_15/doc/userdoc.rst>
Example 16: DiffBot with chained controllers <../example_16/doc/userdoc.rst>
Example 17: RRBot with Hardware Component that publishes diagnostics <../example_17/doc/userdoc.rst>
85 changes: 85 additions & 0 deletions example_17/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
cmake_minimum_required(VERSION 3.16)
project(ros2_control_demo_example_17 LANGUAGES CXX)

find_package(ros2_control_cmake REQUIRED)
set_compiler_options()
export_windows_symbols()

# find dependencies
set(THIS_PACKAGE_INCLUDE_DEPENDS
hardware_interface
pluginlib
rclcpp
rclcpp_lifecycle
)

# Specify the required version of ros2_control
find_package(controller_manager 4.0.0)
# Handle the case where the required version is not found
if(NOT controller_manager_FOUND)
message(FATAL_ERROR "ros2_control version 4.0.0 or higher is required. "
"Are you using the correct branch of the ros2_control_demos repository?")
endif()

# find dependencies
find_package(backward_ros REQUIRED)
find_package(ament_cmake REQUIRED)
foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_DEPENDS})
find_package(${Dependency} REQUIRED)
endforeach()

## COMPILE
add_library(
ros2_control_demo_example_17
SHARED
hardware/rrbot.cpp
)
target_compile_features(ros2_control_demo_example_17 PUBLIC cxx_std_17)
target_include_directories(ros2_control_demo_example_17 PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/hardware/include>
$<INSTALL_INTERFACE:include/ros2_control_demo_example_17>
)
target_link_libraries(ros2_control_demo_example_17 PUBLIC
hardware_interface::hardware_interface
pluginlib::pluginlib
rclcpp::rclcpp
rclcpp_lifecycle::rclcpp_lifecycle
)

# Export hardware plugins
pluginlib_export_plugin_description_file(hardware_interface ros2_control_demo_example_17.xml)

# INSTALL
install(
DIRECTORY hardware/include/
DESTINATION include/ros2_control_demo_example_17
)
install(
DIRECTORY description/launch description/ros2_control description/urdf
DESTINATION share/ros2_control_demo_example_17
)
install(
DIRECTORY bringup/launch bringup/config
DESTINATION share/ros2_control_demo_example_17
)
install(TARGETS ros2_control_demo_example_17
EXPORT export_ros2_control_demo_example_17
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)

if(BUILD_TESTING)
find_package(ament_cmake_pytest REQUIRED)

ament_add_pytest_test(example_17_urdf_xacro test/test_urdf_xacro.py)
ament_add_pytest_test(view_example_17_launch test/test_view_robot_launch.py)
ament_add_pytest_test(run_example_17_launch test/test_rrbot_launch.py)
ament_add_pytest_test(run_example_17_launch_cli_direct test/test_rrbot_launch_cli_direct.py)
endif()


## EXPORTS
ament_export_targets(export_ros2_control_demo_example_17 HAS_LIBRARY_TARGET)
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})
ament_package()
5 changes: 5 additions & 0 deletions example_17/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ros2_control_demo_example_17

This example shows how to publish diagnostics from a hardware component using the Executor passed from Controller Manager.

Find the documentation in [doc/userdoc.rst](doc/userdoc.rst) or on [control.ros.org](https://control.ros.org/master/doc/ros2_control_demos/example_17/doc/userdoc.html).
15 changes: 15 additions & 0 deletions example_17/bringup/config/rrbot_controllers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
controller_manager:
ros__parameters:
update_rate: 10 # Hz

joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster


forward_position_controller:
ros__parameters:
type: forward_command_controller/ForwardCommandController
joints:
- joint1
- joint2
interface_name: position
11 changes: 11 additions & 0 deletions example_17/bringup/config/rrbot_forward_position_publisher.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
publisher_forward_position_controller:
ros__parameters:

wait_sec_between_publish: 5
publish_topic: "/forward_position_controller/commands"

goal_names: ["pos1", "pos2", "pos3", "pos4"]
pos1: [0.785, 0.785]
pos2: [0.0, 0.0]
pos3: [-0.785, -0.785]
pos4: [0.0, 0.0]
24 changes: 24 additions & 0 deletions example_17/bringup/config/rrbot_joint_trajectory_publisher.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
publisher_joint_trajectory_controller:
ros__parameters:

controller_name: "joint_trajectory_position_controller"
wait_sec_between_publish: 6

goal_names: ["pos1", "pos2", "pos3", "pos4"]
pos1:
positions: [0.785, 0.785]
pos2:
positions: [0.0, 0.0]
pos3:
positions: [-0.785, -0.785]
pos4:
positions: [0.0, 0.0]

joints:
- joint1
- joint2

check_starting_point: false
starting_point_limits:
joint1: [-0.1,0.1]
joint2: [-0.1,0.1]
22 changes: 22 additions & 0 deletions example_17/bringup/config/rrbot_jtc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
joint_trajectory_position_controller:
ros__parameters:
type: joint_trajectory_controller/JointTrajectoryController

joints:
- joint1
- joint2

command_interfaces:
- position

state_interfaces:
- position

action_monitor_rate: 20.0 # Defaults to 20

allow_partial_joints_goal: false # Defaults to false
interpolate_from_desired_state: true
allow_integration_in_goal_trajectories: true
constraints:
stopped_velocity_tolerance: 0.01 # Defaults to 0.01
goal_time: 0.0 # Defaults to 0.0 (start immediately)
125 changes: 125 additions & 0 deletions example_17/bringup/launch/rrbot.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Copyright 2021 Stogl Robotics Consulting UG (haftungsbeschränkt)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, RegisterEventHandler
from launch.conditions import IfCondition
from launch.event_handlers import OnProcessExit
from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution

from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare


def generate_launch_description():
# Declare arguments
declared_arguments = []
declared_arguments.append(
DeclareLaunchArgument(
"gui",
default_value="true",
description="Start RViz2 automatically with this launch file.",
)
)

# Initialize Arguments
gui = LaunchConfiguration("gui")

# Get URDF via xacro
robot_description_content = Command(
[
PathJoinSubstitution([FindExecutable(name="xacro")]),
" ",
PathJoinSubstitution(
[
FindPackageShare("ros2_control_demo_example_17"),
"urdf",
"rrbot.urdf.xacro",
]
),
]
)
robot_description = {"robot_description": robot_description_content}

robot_controllers = PathJoinSubstitution(
[
FindPackageShare("ros2_control_demo_example_17"),
"config",
"rrbot_controllers.yaml",
]
)
rviz_config_file = PathJoinSubstitution(
[FindPackageShare("ros2_control_demo_description"), "rrbot/rviz", "rrbot.rviz"]
)

control_node = Node(
package="controller_manager",
executable="ros2_control_node",
parameters=[robot_controllers],
output="both",
)
robot_state_pub_node = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
output="both",
parameters=[robot_description],
)
rviz_node = Node(
package="rviz2",
executable="rviz2",
name="rviz2",
output="log",
arguments=["-d", rviz_config_file],
condition=IfCondition(gui),
)

joint_state_broadcaster_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["joint_state_broadcaster"],
)

robot_controller_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["forward_position_controller", "--param-file", robot_controllers],
)

# Delay rviz start after `joint_state_broadcaster`
delay_rviz_after_joint_state_broadcaster_spawner = RegisterEventHandler(
event_handler=OnProcessExit(
target_action=joint_state_broadcaster_spawner,
on_exit=[rviz_node],
)
)

# Delay start of joint_state_broadcaster after `robot_controller`
# TODO(anyone): This is a workaround for flaky tests. Remove when fixed.
delay_joint_state_broadcaster_after_robot_controller_spawner = RegisterEventHandler(
event_handler=OnProcessExit(
target_action=robot_controller_spawner,
on_exit=[joint_state_broadcaster_spawner],
)
)

nodes = [
control_node,
robot_state_pub_node,
robot_controller_spawner,
delay_rviz_after_joint_state_broadcaster_spawner,
delay_joint_state_broadcaster_after_robot_controller_spawner,
]

return LaunchDescription(declared_arguments + nodes)
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2021 Stogl Robotics Consulting UG (haftungsbeschränkt)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from launch import LaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare


def generate_launch_description():

position_goals = PathJoinSubstitution(
[
FindPackageShare("ros2_control_demo_example_17"),
"config",
"rrbot_forward_position_publisher.yaml",
]
)

return LaunchDescription(
[
Node(
package="ros2_controllers_test_nodes",
executable="publisher_forward_position_controller",
name="publisher_forward_position_controller",
parameters=[position_goals],
output="both",
)
]
)
Loading