├── LICENSE ├── launch └── view_robot_launch.py ├── lesson_urdf └── __init__.py ├── meshes ├── collision │ ├── arm_link.stl │ ├── arm_link_twist_1.stl │ ├── arm_link_twist_2.stl │ └── gripper.stl └── visual │ ├── arm_link.stl │ ├── arm_link_twist_1.stl │ ├── arm_link_twist_2.stl │ └── gripper.stl ├── package.xml ├── readme.md ├── resource └── lesson_urdf ├── robotplanar.PNG ├── rviz └── view.rviz ├── setup.cfg ├── setup.py ├── test ├── test_copyright.py ├── test_flake8.py └── test_pep257.py └── urdf └── planar_3dof.urdf /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 olmerg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /launch/view_robot_launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ament_index_python.packages import get_package_share_directory 4 | 5 | from launch import LaunchDescription 6 | from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription 7 | from launch.conditions import IfCondition 8 | from launch.launch_description_sources import PythonLaunchDescriptionSource 9 | from launch.substitutions import LaunchConfiguration, PythonExpression 10 | from launch_ros.actions import Node 11 | 12 | 13 | def generate_launch_description(): 14 | # Get the launch directory 15 | bringup_dir = get_package_share_directory('lesson_urdf') 16 | launch_dir = os.path.join(bringup_dir, 'launch') 17 | 18 | # Launch configuration variables specific to simulation 19 | rviz_config_file = LaunchConfiguration('rviz_config_file') 20 | use_robot_state_pub = LaunchConfiguration('use_robot_state_pub') 21 | use_joint_state_pub = LaunchConfiguration('use_joint_state_pub') 22 | use_rviz = LaunchConfiguration('use_rviz') 23 | urdf_file= LaunchConfiguration('urdf_file') 24 | 25 | declare_rviz_config_file_cmd = DeclareLaunchArgument( 26 | 'rviz_config_file', 27 | default_value=os.path.join(bringup_dir, 'rviz', 'view.rviz'), 28 | description='Full path to the RVIZ config file to use') 29 | declare_use_robot_state_pub_cmd = DeclareLaunchArgument( 30 | 'use_robot_state_pub', 31 | default_value='True', 32 | description='Whether to start the robot state publisher') 33 | declare_use_joint_state_pub_cmd = DeclareLaunchArgument( 34 | 'use_joint_state_pub', 35 | default_value='True', 36 | description='Whether to start the joint state publisher') 37 | declare_use_rviz_cmd = DeclareLaunchArgument( 38 | 'use_rviz', 39 | default_value='True', 40 | description='Whether to start RVIZ') 41 | 42 | declare_urdf_cmd = DeclareLaunchArgument( 43 | 'urdf_file', 44 | default_value=os.path.join(bringup_dir, 'urdf', 'planar_3dof.urdf'), 45 | description='Whether to start RVIZ') 46 | 47 | 48 | start_robot_state_publisher_cmd = Node( 49 | condition=IfCondition(use_robot_state_pub), 50 | package='robot_state_publisher', 51 | executable='robot_state_publisher', 52 | name='robot_state_publisher', 53 | output='screen', 54 | #parameters=[{'use_sim_time': use_sim_time}], 55 | arguments=[urdf_file]) 56 | 57 | start_joint_state_publisher_cmd = Node( 58 | condition=IfCondition(use_joint_state_pub), 59 | package='joint_state_publisher_gui', 60 | executable='joint_state_publisher_gui', 61 | name='joint_state_publisher_gui', 62 | output='screen', 63 | arguments=[urdf_file]) 64 | 65 | rviz_cmd = Node( 66 | condition=IfCondition(use_rviz), 67 | package='rviz2', 68 | executable='rviz2', 69 | name='rviz2', 70 | arguments=['-d', rviz_config_file], 71 | output='screen') 72 | 73 | 74 | # Create the launch description and populate 75 | ld = LaunchDescription() 76 | 77 | # Declare the launch options 78 | ld.add_action(declare_rviz_config_file_cmd) 79 | ld.add_action(declare_urdf_cmd) 80 | ld.add_action(declare_use_robot_state_pub_cmd) 81 | ld.add_action(declare_use_joint_state_pub_cmd) 82 | ld.add_action(declare_use_rviz_cmd) 83 | 84 | 85 | # Add any conditioned actions 86 | ld.add_action(start_joint_state_publisher_cmd) 87 | ld.add_action(start_robot_state_publisher_cmd) 88 | ld.add_action(rviz_cmd) 89 | 90 | return ld 91 | 92 | -------------------------------------------------------------------------------- /lesson_urdf/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/lesson_urdf/__init__.py -------------------------------------------------------------------------------- /meshes/collision/arm_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/collision/arm_link.stl -------------------------------------------------------------------------------- /meshes/collision/arm_link_twist_1.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/collision/arm_link_twist_1.stl -------------------------------------------------------------------------------- /meshes/collision/arm_link_twist_2.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/collision/arm_link_twist_2.stl -------------------------------------------------------------------------------- /meshes/collision/gripper.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/collision/gripper.stl -------------------------------------------------------------------------------- /meshes/visual/arm_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/visual/arm_link.stl -------------------------------------------------------------------------------- /meshes/visual/arm_link_twist_1.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/visual/arm_link_twist_1.stl -------------------------------------------------------------------------------- /meshes/visual/arm_link_twist_2.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/visual/arm_link_twist_2.stl -------------------------------------------------------------------------------- /meshes/visual/gripper.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/meshes/visual/gripper.stl -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | lesson_urdf 5 | 0.0.0 6 | TODO: Package description 7 | ros-industrial 8 | TODO: License declaration 9 | 10 | ament_copyright 11 | ament_flake8 12 | ament_pep257 13 | python3-pytest 14 | 15 | urdf 16 | launch_ros 17 | launch_ros 18 | robot_state_publisher 19 | joint_state_publisher_gui 20 | 21 | 22 | ament_python 23 | 24 | 25 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Planar 3DOF manipulator robot 3 | 4 | This project implements a 3D planar robot in urdf. It also contain a launch with a *robot_state_publisher* and a *joint_state_publisher_gui* 5 | 6 | This urdf create a planar robot with the next chain: 7 | ``` 8 | robot name is: planar_3dof 9 | ---------- Successfully Parsed XML --------------- 10 | root Link: world has 1 child(ren) 11 | child(1): base_link 12 | child(1): link_1 13 | child(1): link_2 14 | child(1): gripper 15 | child(1): end 16 | 17 | ``` 18 | 19 | 20 | 21 | 22 | This is an adaptation of an old example of ros industrial tutorial(before [docs](https://industrial-training-master.readthedocs.io/) ) about how to create and urdf files 23 | 24 | ![](robotplanar.PNG) 25 | 26 | where, $l_1=l_2=0.5$ y $l_3=0.18$ 27 | 28 | **TODO: put the instruction about how to create the urdf** 29 | The full name of URDF (United Robotics Description Format) is a language format used to describe robots in the XML grammar framework. URDF is very popular in ROS world. We can model the robot through URDF and put it in ROS for simulation and analysis. 30 | 31 | The robot should be described through a tags, where the ***link*** represent the geometry of the robot and the ***joint*** represent the articulation or degree of fredoom of the robot. The tags are documented in [wiki ros](http://wiki.ros.org/urdf/XML), where can be find other tags like sensor or transmission which let to describe this part of robot. 32 | 33 | Steps to reproduce this repository: 34 | - open a terminal inside the docker of [ros2_start](https://github.com/olmerg/ros2_start) or create a workspace. 35 | 36 | - [create a package](https://docs.ros.org/en/foxy/Tutorials/Creating-Your-First-ROS2-Package.html): 37 | ``` 38 | cd src 39 | ros2 pkg create --build-type ament_python lesson_urdf 40 | ``` 41 | - Edit the files package.xml to add the next dependencies and your information about the package 42 | ``` 43 | urdf 44 | launch_ros 45 | launch_ros 46 | robot_state_publisher 47 | joint_state_publisher_gui 48 | ``` 49 | - make a folder urdf inside package 50 | ``` 51 | cd src/lesson_urdf 52 | mkdir urdf 53 | gedit planar_3dof.urdf 54 | ``` 55 | - Create the tag robot inside the file 56 | ``` 57 | 58 | 59 | 60 | ``` 61 | - create a link without geometry which is the world (inside tag ***robot***) 62 | ``` 63 | 64 | ``` 65 | - create a link **base_link** which describe the base of the robot of the figure. Note that this link has a ***visual*** tag which describe the ***geometry*** an ***material*** of the piece. It also contain another geometry which is the ***collision*** geometry which could describe a simplified geometry to check collision or other tasks. In this case we represent the base of the robot with a ***cylinder*** of length 0.1 and width 0.2. The cilynde ris created 66 | ``` 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | ``` 87 | - create a ***joint*** fixed to the world 88 | ``` 89 | 90 | 91 | 92 | 93 | ``` 94 | - now create the ***link*** link_1, but now the geometry will be an stl file inside the folder meshes of our project (lesson_urdf). Note that we also can add ***inertial*** propierties of the robot like center of mass and inertia matrix of each link. Also note that collision and visual geometry could be diferrent. Here the cylinder made to simplify the link has a length 0.5 and radius 0.05, but this geometry is created over z axis since -0.25, so in ***origin*** we rotate the figure in y 90 degrees(1.5708) and translate in x 0.25 to start in zero. 95 | ``` 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | ``` 117 | - now we create the ***joint*** with ***parent*** the base_link and ***child*** the link_1 of type *revolute*. Note that here the ***axis*** of rotation is over z and the link_1 is translated 0.05 over z from the origin of the base_link. 118 | ``` 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | ``` 127 | - Repetae the process for *link_2*, *gripper* and a link without geomtery *end* 128 | ... 129 | 130 | - save the file 131 | - now copy the meshes,rviz and launch folder (TODO [tutorial about launch](https://docs.ros.org/en/foxy/Tutorials/Launch-system.html)) 132 | - configure in setup.py the files to be copy: 133 | - Add the library at the beginning of the file 134 | ``` 135 | from glob import glob 136 | ``` 137 | - append these lines inside data_files 138 | ``` 139 | ('share/' + package_name, glob('launch/*.py')), 140 | ('share/' + package_name+'/urdf/', glob('urdf/*')), 141 | ('share/' + package_name+'/rviz/', glob('rviz/*')), 142 | ('share/' + package_name+'/meshes/collision/', glob('meshes/collision/*')), 143 | ('share/' + package_name+'/meshes/visual/', glob('meshes/visual/*')), 144 | ``` 145 | - compile the workspace 146 | ``` 147 | colcon build --symlink-install 148 | ``` 149 | - add to path the workspace 150 | ``` 151 | . install/setup.bash 152 | ``` 153 | - run the launch file 154 | ``` 155 | ros2 launch lesson_urdf view_robot_launch.py 156 | ``` 157 | 158 | 159 | 160 | 161 | Some error could be: 162 | To execute this package please add this to the .bashrc or to the specific console ([Show basic URDF model in Rviz2](https://answers.ros.org/question/348984/show-basic-urdf-model-in-rviz2/) ) 163 | 164 | echo "export LC_NUMERIC="en_US.UTF-8"" >> ~/.bashrc 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /resource/lesson_urdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/resource/lesson_urdf -------------------------------------------------------------------------------- /robotplanar.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olmerg/lesson_urdf/e12b2a3180acb330076aefcb270f457a8fae5e9a/robotplanar.PNG -------------------------------------------------------------------------------- /rviz/view.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz_common/Displays 3 | Help Height: 138 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /Global Options1 8 | - /Status1 9 | Splitter Ratio: 0.5 10 | Tree Height: 442 11 | - Class: rviz_common/Selection 12 | Name: Selection 13 | - Class: rviz_common/Tool Properties 14 | Expanded: 15 | - /2D Goal Pose1 16 | - /Publish Point1 17 | Name: Tool Properties 18 | Splitter Ratio: 0.5886790156364441 19 | - Class: rviz_common/Views 20 | Expanded: 21 | - /Current View1 22 | Name: Views 23 | Splitter Ratio: 0.5 24 | Visualization Manager: 25 | Class: "" 26 | Displays: 27 | - Alpha: 0.5 28 | Cell Size: 1 29 | Class: rviz_default_plugins/Grid 30 | Color: 160; 160; 164 31 | Enabled: true 32 | Line Style: 33 | Line Width: 0.029999999329447746 34 | Value: Lines 35 | Name: Grid 36 | Normal Cell Count: 0 37 | Offset: 38 | X: 0 39 | Y: 0 40 | Z: 0 41 | Plane: XY 42 | Plane Cell Count: 10 43 | Reference Frame: 44 | Value: true 45 | - Alpha: 1 46 | Class: rviz_default_plugins/RobotModel 47 | Collision Enabled: false 48 | Description File: "" 49 | Description Source: Topic 50 | Description Topic: 51 | Depth: 5 52 | Durability Policy: Volatile 53 | History Policy: Keep Last 54 | Reliability Policy: Reliable 55 | Value: "/robot_description" 56 | Enabled: true 57 | Links: 58 | All Links Enabled: true 59 | Expand Joint Details: false 60 | Expand Link Details: false 61 | Expand Tree: false 62 | Link Tree Style: "" 63 | Name: RobotModel 64 | TF Prefix: "" 65 | Update Interval: 0 66 | Value: true 67 | Visual Enabled: true 68 | - Class: rviz_default_plugins/TF 69 | Enabled: true 70 | Frame Timeout: 15 71 | Frames: 72 | All Enabled: true 73 | Marker Scale: 1 74 | Name: TF 75 | Show Arrows: true 76 | Show Axes: true 77 | Show Names: false 78 | Tree: 79 | {} 80 | Update Interval: 0 81 | Value: true 82 | Enabled: true 83 | Global Options: 84 | Background Color: 48; 48; 48 85 | Fixed Frame: world 86 | Frame Rate: 30 87 | Name: root 88 | Tools: 89 | - Class: rviz_default_plugins/Interact 90 | Hide Inactive Objects: true 91 | - Class: rviz_default_plugins/MoveCamera 92 | - Class: rviz_default_plugins/Select 93 | - Class: rviz_default_plugins/FocusCamera 94 | - Class: rviz_default_plugins/Measure 95 | Line color: 128; 128; 0 96 | - Class: rviz_default_plugins/SetInitialPose 97 | Topic: 98 | Depth: 5 99 | Durability Policy: Volatile 100 | History Policy: Keep Last 101 | Reliability Policy: Reliable 102 | Value: /initialpose 103 | - Class: rviz_default_plugins/SetGoal 104 | Topic: 105 | Depth: 5 106 | Durability Policy: Volatile 107 | History Policy: Keep Last 108 | Reliability Policy: Reliable 109 | Value: /goal_pose 110 | - Class: rviz_default_plugins/PublishPoint 111 | Single click: true 112 | Topic: 113 | Depth: 5 114 | Durability Policy: Volatile 115 | History Policy: Keep Last 116 | Reliability Policy: Reliable 117 | Value: /clicked_point 118 | Transformation: 119 | Current: 120 | Class: rviz_default_plugins/TF 121 | Value: true 122 | Views: 123 | Current: 124 | Class: rviz_default_plugins/Orbit 125 | Distance: 10 126 | Enable Stereo Rendering: 127 | Stereo Eye Separation: 0.05999999865889549 128 | Stereo Focal Distance: 1 129 | Swap Stereo Eyes: false 130 | Value: false 131 | Focal Point: 132 | X: 0 133 | Y: 0 134 | Z: 0 135 | Focal Shape Fixed Size: true 136 | Focal Shape Size: 0.05000000074505806 137 | Invert Z Axis: false 138 | Name: Current View 139 | Near Clip Distance: 0.009999999776482582 140 | Pitch: 0.785398006439209 141 | Target Frame: 142 | Value: Orbit (rviz) 143 | Yaw: 0.785398006439209 144 | Saved: ~ 145 | Window Geometry: 146 | Displays: 147 | collapsed: false 148 | Height: 846 149 | Hide Left Dock: false 150 | Hide Right Dock: false 151 | QMainWindow State: 000000ff00000000fd0000000400000000000001f7000002b2fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b000000b000fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000006e000002b20000018200fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000015f000002b2fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000006e000002b20000013200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000142000002b200000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 152 | Selection: 153 | collapsed: false 154 | Tool Properties: 155 | collapsed: false 156 | Views: 157 | collapsed: false 158 | Width: 1200 159 | X: 144 160 | Y: 60 161 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script-dir=$base/lib/lesson_urdf2 3 | [install] 4 | install-scripts=$base/lib/lesson_urdf2 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from glob import glob 3 | 4 | package_name = 'lesson_urdf' 5 | 6 | setup( 7 | name=package_name, 8 | version='0.0.0', 9 | packages=[package_name], 10 | data_files=[ 11 | ('share/ament_index/resource_index/packages', 12 | ['resource/' + package_name]), 13 | ('share/' + package_name, ['package.xml']), 14 | ('share/' + package_name, glob('launch/*.py')), 15 | ('share/' + package_name+'/urdf/', glob('urdf/*')), 16 | ('share/' + package_name+'/rviz/', glob('rviz/*')), 17 | ('share/' + package_name+'/meshes/collision/', glob('meshes/collision/*')), 18 | ('share/' + package_name+'/meshes/visual/', glob('meshes/visual/*')), 19 | ], 20 | install_requires=['setuptools'], 21 | zip_safe=True, 22 | maintainer='ros-industrial', 23 | maintainer_email='olmer@gmail.com', 24 | description='TODO: Package description', 25 | license='TODO: License declaration', 26 | tests_require=['pytest'], 27 | entry_points={ 28 | 'console_scripts': [ 29 | ], 30 | }, 31 | ) 32 | -------------------------------------------------------------------------------- /test/test_copyright.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Open Source Robotics Foundation, Inc. 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 ament_copyright.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.copyright 20 | @pytest.mark.linter 21 | def test_copyright(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found errors' 24 | -------------------------------------------------------------------------------- /test/test_flake8.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Open Source Robotics Foundation, Inc. 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 ament_flake8.main import main_with_errors 16 | import pytest 17 | 18 | 19 | @pytest.mark.flake8 20 | @pytest.mark.linter 21 | def test_flake8(): 22 | rc, errors = main_with_errors(argv=[]) 23 | assert rc == 0, \ 24 | 'Found %d code style errors / warnings:\n' % len(errors) + \ 25 | '\n'.join(errors) 26 | -------------------------------------------------------------------------------- /test/test_pep257.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Open Source Robotics Foundation, Inc. 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 ament_pep257.main import main 16 | import pytest 17 | 18 | 19 | @pytest.mark.linter 20 | @pytest.mark.pep257 21 | def test_pep257(): 22 | rc = main(argv=['.', 'test']) 23 | assert rc == 0, 'Found code style errors / warnings' 24 | -------------------------------------------------------------------------------- /urdf/planar_3dof.urdf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | --------------------------------------------------------------------------------