├── .pre-commit-config.yaml ├── CHANGELOG.rst ├── CMakeLists.txt ├── LICENSE ├── README.md ├── config └── urdf.rviz ├── launch ├── description.launch.py └── display.launch.py ├── package.xml └── setup.cfg /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | hooks: 4 | - id: end-of-file-fixer 5 | - id: trailing-whitespace 6 | - id: check-merge-conflict 7 | - id: mixed-line-ending 8 | - id: check-executables-have-shebangs 9 | - id: check-shebang-scripts-are-executable 10 | - id: detect-private-key 11 | - id: destroyed-symlinks 12 | - id: check-symlinks 13 | - id: check-case-conflict 14 | - id: check-ast 15 | - id: double-quote-string-fixer 16 | - id: requirements-txt-fixer 17 | - id: check-xml 18 | rev: v5.0.0 19 | - repo: https://github.com/codespell-project/codespell 20 | hooks: 21 | - id: codespell 22 | args: 23 | - --write-changes 24 | rev: v2.4.1 25 | - repo: https://github.com/hhatto/autopep8 26 | hooks: 27 | - id: autopep8 28 | rev: v2.3.2 29 | - repo: https://github.com/PyCQA/flake8 30 | hooks: 31 | - id: flake8 32 | rev: 7.2.0 33 | ci: 34 | autoupdate_schedule: quarterly 35 | -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package urdf_launch 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.1.0 (2023-08-09) 6 | ------------------ 7 | * Initial Package 8 | * Contributors: David V. Lu!! 9 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(urdf_launch) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | install( 7 | DIRECTORY config launch 8 | DESTINATION share/${PROJECT_NAME} 9 | ) 10 | 11 | ament_package() 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2023, Metro Robots 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # urdf_launch 2 | 3 | This package contains launch files and configurations for common URDF operations. 4 | 5 | ## Load Description 6 | 7 | [`description.launch.py`](launch/description.launch.py) 8 | * Loads the URDF/Xacro robot model as a parameter, based on launch arguments 9 | * Launches a single node, `robot_state_publisher`, with the robot model parameter. 10 | * This results in the robot description being available as a topic. 11 | 12 | The result is that you can perform the above actions with just 5 lines (not including boilerplate) in your own launch file. 13 | 14 | ```python 15 | from launch import LaunchDescription 16 | from launch.actions import IncludeLaunchDescription 17 | from launch.substitutions import PathJoinSubstitution 18 | from launch_ros.substitutions import FindPackageShare 19 | 20 | 21 | def generate_launch_description(): 22 | ld = LaunchDescription() 23 | 24 | ld.add_action(IncludeLaunchDescription( 25 | PathJoinSubstitution([FindPackageShare('urdf_launch'), 'launch', 'description.launch.py']), 26 | launch_arguments={ 27 | 'urdf_package': 'turtlebot3_description', 28 | 'urdf_package_path': PathJoinSubstitution(['urdf', 'turtlebot3_burger.urdf'])}.items() 29 | )) 30 | 31 | return ld 32 | 33 | ``` 34 | 35 | ## Display Robot Model 36 | When developing a URDF robot model, it is often useful to display just the robot model in RViz. [`display.launch.py`](launch/display.launch.py) does the above tasks PLUS: 37 | * Launches RViz with a preconfigured setup 38 | * Launches a joint state publisher (with optional GUI) 39 | 40 | This can be used in its own launch file, like the previous example, or can be done via command line, e.g. 41 | 42 | ros2 launch urdf_launch display.launch.py urdf_package:=turtlebot3_description urdf_package_path:=urdf/turtlebot3_burger.urdf 43 | -------------------------------------------------------------------------------- /config/urdf.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz_common/Displays 3 | Name: Displays 4 | - Class: rviz_common/Views 5 | Name: Views 6 | Visualization Manager: 7 | Displays: 8 | - Class: rviz_default_plugins/Grid 9 | Name: Grid 10 | Value: true 11 | - Alpha: 0.8 12 | Class: rviz_default_plugins/RobotModel 13 | Description Topic: 14 | Value: /robot_description 15 | Name: RobotModel 16 | Value: true 17 | - Class: rviz_default_plugins/TF 18 | Name: TF 19 | Value: true 20 | Global Options: 21 | Fixed Frame: base_link 22 | Tools: 23 | - Class: rviz_default_plugins/MoveCamera 24 | Value: true 25 | Views: 26 | Current: 27 | Class: rviz_default_plugins/Orbit 28 | Distance: 1.7 29 | Name: Current View 30 | Pitch: 0.33 31 | Value: Orbit (rviz) 32 | Yaw: 5.5 33 | Window Geometry: 34 | Height: 800 35 | Width: 1200 36 | -------------------------------------------------------------------------------- /launch/description.launch.py: -------------------------------------------------------------------------------- 1 | from launch import LaunchDescription 2 | from launch.actions import DeclareLaunchArgument 3 | from launch.substitutions import Command 4 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 5 | 6 | 7 | from launch_ros.actions import Node 8 | from launch_ros.parameter_descriptions import ParameterValue 9 | from launch_ros.substitutions import FindPackageShare 10 | 11 | 12 | def generate_launch_description(): 13 | ld = LaunchDescription() 14 | ld.add_action(DeclareLaunchArgument('urdf_package', 15 | description='The package where the robot description is located')) 16 | ld.add_action(DeclareLaunchArgument('urdf_package_path', 17 | description='The path to the robot description relative to the package root')) 18 | 19 | package_dir = FindPackageShare(LaunchConfiguration('urdf_package')) 20 | urdf_path = PathJoinSubstitution([package_dir, LaunchConfiguration('urdf_package_path')]) 21 | 22 | robot_description_content = ParameterValue(Command(['xacro ', urdf_path]), value_type=str) 23 | 24 | robot_state_publisher_node = Node(package='robot_state_publisher', 25 | executable='robot_state_publisher', 26 | parameters=[{ 27 | 'robot_description': robot_description_content, 28 | }]) 29 | 30 | ld.add_action(robot_state_publisher_node) 31 | return ld 32 | -------------------------------------------------------------------------------- /launch/display.launch.py: -------------------------------------------------------------------------------- 1 | from launch import LaunchDescription 2 | from launch.actions import DeclareLaunchArgument 3 | from launch.actions import IncludeLaunchDescription 4 | from launch.conditions import IfCondition, UnlessCondition 5 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 6 | 7 | from launch_ros.actions import Node 8 | from launch_ros.substitutions import FindPackageShare 9 | 10 | 11 | def generate_launch_description(): 12 | ld = LaunchDescription() 13 | 14 | urdf_launch_package = FindPackageShare('urdf_launch') 15 | 16 | ld.add_action(DeclareLaunchArgument(name='jsp_gui', default_value='true', choices=['true', 'false'], 17 | description='Flag to enable joint_state_publisher_gui')) 18 | 19 | default_rviz_config_path = PathJoinSubstitution([urdf_launch_package, 'config', 'urdf.rviz']) 20 | ld.add_action(DeclareLaunchArgument(name='rviz_config', default_value=default_rviz_config_path, 21 | description='Absolute path to rviz config file')) 22 | 23 | # need to manually pass configuration in because of https://github.com/ros2/launch/issues/313 24 | ld.add_action(IncludeLaunchDescription( 25 | PathJoinSubstitution([urdf_launch_package, 'launch', 'description.launch.py']), 26 | launch_arguments={ 27 | 'urdf_package': LaunchConfiguration('urdf_package'), 28 | 'urdf_package_path': LaunchConfiguration('urdf_package_path')}.items() 29 | )) 30 | 31 | # Depending on gui parameter, either launch joint_state_publisher or joint_state_publisher_gui 32 | ld.add_action(Node( 33 | package='joint_state_publisher', 34 | executable='joint_state_publisher', 35 | condition=UnlessCondition(LaunchConfiguration('jsp_gui')) 36 | )) 37 | 38 | ld.add_action(Node( 39 | package='joint_state_publisher_gui', 40 | executable='joint_state_publisher_gui', 41 | condition=IfCondition(LaunchConfiguration('jsp_gui')) 42 | )) 43 | 44 | ld.add_action(Node( 45 | package='rviz2', 46 | executable='rviz2', 47 | output='screen', 48 | arguments=['-d', LaunchConfiguration('rviz_config')], 49 | )) 50 | return ld 51 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | urdf_launch 5 | 0.1.1 6 | Launch files for common URDF operations 7 | David V. Lu!! 8 | BSD 3-clause 9 | 10 | ament_cmake 11 | rviz_common 12 | rviz_default_plugins 13 | joint_state_publisher 14 | joint_state_publisher_gui 15 | launch_ros 16 | robot_state_publisher 17 | rviz2 18 | xacro 19 | 20 | 21 | ament_cmake 22 | 23 | 24 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max_line_length=120 3 | --------------------------------------------------------------------------------