From e938b6921f320f848256deecace5dee52f5bfcb2 Mon Sep 17 00:00:00 2001 From: Yoo Hee Sung <145455299+hs-YOO12@users.noreply.github.com> Date: Thu, 27 Aug 2026 11:04:29 +0900 Subject: [PATCH] Initial commit of duru_urdf package Co-Authored-By: Claude Sonnet 5 --- config/display.rviz | 237 ++++++++++++++++++++++++++++++ duru_urdf_description/__init__.py | 0 launch/display.launch.py | 64 ++++++++ launch/gazebo.launch.py | 73 +++++++++ meshes/base_link.stl | Bin 0 -> 25684 bytes meshes/fwl_1_1.stl | Bin 0 -> 20884 bytes meshes/fwr_1_1.stl | Bin 0 -> 20884 bytes meshes/imu_1.stl | Bin 0 -> 684 bytes meshes/lidar_1.stl | Bin 0 -> 76384 bytes meshes/rwl_1_1.stl | Bin 0 -> 20884 bytes meshes/rwr_1_1.stl | Bin 0 -> 20884 bytes package.xml | 24 +++ resource/duru_urdf_description | 0 setup.cfg | 4 + setup.py | 31 ++++ test/test_copyright.py | 23 +++ test/test_flake8.py | 25 ++++ test/test_pep257.py | 23 +++ urdf/duru_urdf.gazebo | 59 ++++++++ urdf/duru_urdf.trans | 48 ++++++ urdf/duru_urdf.xacro | 194 ++++++++++++++++++++++++ urdf/materials.xacro | 8 + 22 files changed, 813 insertions(+) create mode 100644 config/display.rviz create mode 100644 duru_urdf_description/__init__.py create mode 100644 launch/display.launch.py create mode 100644 launch/gazebo.launch.py create mode 100644 meshes/base_link.stl create mode 100644 meshes/fwl_1_1.stl create mode 100644 meshes/fwr_1_1.stl create mode 100644 meshes/imu_1.stl create mode 100644 meshes/lidar_1.stl create mode 100644 meshes/rwl_1_1.stl create mode 100644 meshes/rwr_1_1.stl create mode 100644 package.xml create mode 100644 resource/duru_urdf_description create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 test/test_copyright.py create mode 100644 test/test_flake8.py create mode 100644 test/test_pep257.py create mode 100644 urdf/duru_urdf.gazebo create mode 100644 urdf/duru_urdf.trans create mode 100644 urdf/duru_urdf.xacro create mode 100644 urdf/materials.xacro diff --git a/config/display.rviz b/config/display.rviz new file mode 100644 index 0000000..e7136f0 --- /dev/null +++ b/config/display.rviz @@ -0,0 +1,237 @@ +Panels: + - Class: rviz_common/Displays + Help Height: 78 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /Status1 + - /RobotModel1 + - /TF1 + Splitter Ratio: 0.5 + Tree Height: 617 + - Class: rviz_common/Selection + Name: Selection + - Class: rviz_common/Tool Properties + Expanded: + - /2D Goal Pose1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz_common/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz_default_plugins/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Alpha: 1 + Class: rviz_default_plugins/RobotModel + Collision Enabled: false + Description File: "" + Description Source: Topic + Description Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /robot_description + Enabled: true + Links: + All Links Enabled: true + Expand Joint Details: false + Expand Link Details: false + Expand Tree: false + Link Tree Style: Links in Alphabetic Order + back_motor_left_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + back_motor_right_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + back_wheel_left_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + back_wheel_right_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + base_link: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + front_motor_left_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + front_motor_right_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + front_wheel_left_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + front_wheel_right_2: + Alpha: 1 + Show Axes: false + Show Trail: false + Value: true + Name: RobotModel + TF Prefix: "" + Update Interval: 0 + Value: true + Visual Enabled: true + - Class: rviz_default_plugins/TF + Enabled: true + Frame Timeout: 15 + Frames: + All Enabled: true + back_motor_left_2: + Value: true + back_motor_right_2: + Value: true + back_wheel_left_2: + Value: true + back_wheel_right_2: + Value: true + base_link: + Value: true + front_motor_left_2: + Value: true + front_motor_right_2: + Value: true + front_wheel_left_2: + Value: true + front_wheel_right_2: + Value: true + Marker Scale: 0.5 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: false + Tree: + base_link: + back_motor_right_2: + back_wheel_right_2: + {} + back_wheel_left_2: + back_motor_left_2: + {} + front_motor_left_2: + front_wheel_left_2: + {} + front_motor_right_2: + front_wheel_right_2: + {} + Update Interval: 0 + Value: true + Enabled: true + Global Options: + Background Color: 48; 48; 48 + Fixed Frame: base_link + Frame Rate: 30 + Name: root + Tools: + - Class: rviz_default_plugins/Interact + Hide Inactive Objects: true + - Class: rviz_default_plugins/MoveCamera + - Class: rviz_default_plugins/Select + - Class: rviz_default_plugins/FocusCamera + - Class: rviz_default_plugins/Measure + Line color: 128; 128; 0 + - Class: rviz_default_plugins/SetInitialPose + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /initialpose + - Class: rviz_default_plugins/SetGoal + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /goal_pose + - Class: rviz_default_plugins/PublishPoint + Single click: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /clicked_point + Transformation: + Current: + Class: rviz_default_plugins/TF + Value: true + Views: + Current: + Class: rviz_default_plugins/Orbit + Distance: 0.8402727246284485 + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Focal Point: + X: 0 + Y: 0 + Z: 0 + Focal Shape Fixed Size: true + Focal Shape Size: 0.05000000074505806 + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Pitch: 0.6097970008850098 + Target Frame: + Value: Orbit (rviz) + Yaw: 0.5103846192359924 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 846 + Hide Left Dock: false + Hide Right Dock: false + QMainWindow State: 000000ff00000000fd000000040000000000000156000002f4fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000002f4000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f000002f4fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d000002f4000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d006501000000000000045000000000000000000000023f000002f400000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + Selection: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: false + Width: 1200 + X: 201 + Y: 69 diff --git a/duru_urdf_description/__init__.py b/duru_urdf_description/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/launch/display.launch.py b/launch/display.launch.py new file mode 100644 index 0000000..9513e7c --- /dev/null +++ b/launch/display.launch.py @@ -0,0 +1,64 @@ +from launch_ros.actions import Node +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration +from launch.conditions import IfCondition, UnlessCondition +import xacro +import os +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + share_dir = get_package_share_directory('duru_urdf_description') + + xacro_file = os.path.join(share_dir, 'urdf', 'duru_urdf.xacro') + robot_description_config = xacro.process_file(xacro_file) + robot_urdf = robot_description_config.toxml() + + rviz_config_file = os.path.join(share_dir, 'config', 'display.rviz') + + gui_arg = DeclareLaunchArgument( + name='gui', + default_value='True' + ) + + show_gui = LaunchConfiguration('gui') + + robot_state_publisher_node = Node( + package='robot_state_publisher', + executable='robot_state_publisher', + name='robot_state_publisher', + parameters=[ + {'robot_description': robot_urdf} + ] + ) + + joint_state_publisher_node = Node( + condition=UnlessCondition(show_gui), + package='joint_state_publisher', + executable='joint_state_publisher', + name='joint_state_publisher' + ) + + joint_state_publisher_gui_node = Node( + condition=IfCondition(show_gui), + package='joint_state_publisher_gui', + executable='joint_state_publisher_gui', + name='joint_state_publisher_gui' + ) + + rviz_node = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + arguments=['-d', rviz_config_file], + output='screen' + ) + + return LaunchDescription([ + gui_arg, + robot_state_publisher_node, + joint_state_publisher_node, + joint_state_publisher_gui_node, + rviz_node + ]) diff --git a/launch/gazebo.launch.py b/launch/gazebo.launch.py new file mode 100644 index 0000000..11bee0c --- /dev/null +++ b/launch/gazebo.launch.py @@ -0,0 +1,73 @@ +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import PathJoinSubstitution +import os +import xacro +from ament_index_python.packages import get_package_share_directory + + +def generate_launch_description(): + share_dir = get_package_share_directory('duru_urdf_description') + + xacro_file = os.path.join(share_dir, 'urdf', 'duru_urdf.xacro') + robot_description_config = xacro.process_file(xacro_file) + robot_urdf = robot_description_config.toxml() + + robot_state_publisher_node = Node( + package='robot_state_publisher', + executable='robot_state_publisher', + name='robot_state_publisher', + parameters=[ + {'robot_description': robot_urdf} + ] + ) + + joint_state_publisher_node = Node( + package='joint_state_publisher', + executable='joint_state_publisher', + name='joint_state_publisher' + ) + + gazebo_server = IncludeLaunchDescription( + PythonLaunchDescriptionSource([ + PathJoinSubstitution([ + FindPackageShare('gazebo_ros'), + 'launch', + 'gzserver.launch.py' + ]) + ]), + launch_arguments={ + 'pause': 'true' + }.items() + ) + + gazebo_client = IncludeLaunchDescription( + PythonLaunchDescriptionSource([ + PathJoinSubstitution([ + FindPackageShare('gazebo_ros'), + 'launch', + 'gzclient.launch.py' + ]) + ]) + ) + + urdf_spawn_node = Node( + package='gazebo_ros', + executable='spawn_entity.py', + arguments=[ + '-entity', 'duru_urdf', + '-topic', 'robot_description' + ], + output='screen' + ) + + return LaunchDescription([ + robot_state_publisher_node, + joint_state_publisher_node, + gazebo_server, + gazebo_client, + urdf_spawn_node, + ]) diff --git a/meshes/base_link.stl b/meshes/base_link.stl new file mode 100644 index 0000000000000000000000000000000000000000..4678765573887d5dacd1835a6178240a378e3531 GIT binary patch literal 25684 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 F_+Jj5D^&mh literal 0 HcmV?d00001 diff --git a/meshes/fwl_1_1.stl b/meshes/fwl_1_1.stl new file mode 100644 index 0000000000000000000000000000000000000000..00ec579932d497c7a000c88f5ef1c06e0f51dc82 GIT binary patch literal 20884 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 C;+E3@ literal 0 HcmV?d00001 diff --git a/meshes/fwr_1_1.stl b/meshes/fwr_1_1.stl new file mode 100644 index 0000000000000000000000000000000000000000..b4a43f6f58043ec47d3130f87093fce20f7bdd31 GIT binary patch literal 20884 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 literal 0 HcmV?d00001 diff --git a/meshes/imu_1.stl b/meshes/imu_1.stl new file mode 100644 index 0000000000000000000000000000000000000000..57623c6f45bda23b38002b767c135108fc65abca GIT binary patch literal 684 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 UzsmqLXK-zhL{vH;>@AD`2QwefW&i*H literal 0 HcmV?d00001 diff --git a/meshes/rwl_1_1.stl b/meshes/rwl_1_1.stl new file mode 100644 index 0000000000000000000000000000000000000000..f15973bbabb3e9c4e4b05f53c224dae025156da1 GIT binary patch literal 20884 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 E01oAK9smFU literal 0 HcmV?d00001 diff --git a/package.xml b/package.xml new file mode 100644 index 0000000..fbf1ccd --- /dev/null +++ b/package.xml @@ -0,0 +1,24 @@ + + + +duru_urdf_description + 0.0.0 +The duru_urdf_description package + author + TODO: License declaration + + xacro + rviz2 + robot_state_publisher + joint_state_publisher + joint_state_publisher_gui + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/resource/duru_urdf_description b/resource/duru_urdf_description new file mode 100644 index 0000000..e69de29 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..646a7ea --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/duru_urdf_description +[install] +install-scripts=$base/lib/duru_urdf_description diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..cc77d00 --- /dev/null +++ b/setup.py @@ -0,0 +1,31 @@ +from setuptools import setup +import os +from glob import glob + +package_name = 'duru_urdf_description' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + (os.path.join('share', package_name, 'launch'), glob('launch/*.launch.py')), + (os.path.join('share', package_name, 'urdf'), glob('urdf/*')), + (os.path.join('share', package_name, 'meshes'), glob('meshes/*')), + (os.path.join('share', package_name, 'config'), glob('config/*')) + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='author', + maintainer_email='todo@todo.com', + description='The ' + package_name + ' package', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/test/test_copyright.py b/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# 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 ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/test/test_flake8.py b/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# 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 ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/test/test_pep257.py b/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# 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 ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/urdf/duru_urdf.gazebo b/urdf/duru_urdf.gazebo new file mode 100644 index 0000000..b4b6899 --- /dev/null +++ b/urdf/duru_urdf.gazebo @@ -0,0 +1,59 @@ + + + + + + + + + + ${body_color} + 0.2 + 0.2 + true + true + + + + ${body_color} + 0.2 + 0.2 + true + + + + ${body_color} + 0.2 + 0.2 + true + + + + ${body_color} + 0.2 + 0.2 + true + + + + ${body_color} + 0.2 + 0.2 + true + + + + ${body_color} + 0.2 + 0.2 + true + + + + ${body_color} + 0.2 + 0.2 + true + + + diff --git a/urdf/duru_urdf.trans b/urdf/duru_urdf.trans new file mode 100644 index 0000000..b018ab9 --- /dev/null +++ b/urdf/duru_urdf.trans @@ -0,0 +1,48 @@ + + + + + transmission_interface/SimpleTransmission + + hardware_interface/EffortJointInterface + + + hardware_interface/EffortJointInterface + 1 + + + + + transmission_interface/SimpleTransmission + + hardware_interface/EffortJointInterface + + + hardware_interface/EffortJointInterface + 1 + + + + + transmission_interface/SimpleTransmission + + hardware_interface/EffortJointInterface + + + hardware_interface/EffortJointInterface + 1 + + + + + transmission_interface/SimpleTransmission + + hardware_interface/EffortJointInterface + + + hardware_interface/EffortJointInterface + 1 + + + + diff --git a/urdf/duru_urdf.xacro b/urdf/duru_urdf.xacro new file mode 100644 index 0000000..5c68e6a --- /dev/null +++ b/urdf/duru_urdf.xacro @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/urdf/materials.xacro b/urdf/materials.xacro new file mode 100644 index 0000000..34d69f2 --- /dev/null +++ b/urdf/materials.xacro @@ -0,0 +1,8 @@ + + + + + + + +