ROS2-RViz-MoveIt-Gazebo-URDF学习笔记(六)
solidworks导出的URDF文件转到gazebo sim显示默认导出的gazebo.launch.py调整为适配Gazebo sim在is35_description.urdf添加transmissionCMakeLists.txxpackage.xml
修改Moveit2的导出文件修改is35_description.ros2_control.xacro新增is35_description.gazebo.xacro修改is35_description.urdf.xacro修改CMakeLists.txt
编译运行报错warning: Using load_yaml() directly is deprecated. Use xacro.load_yaml() instead.[ign gazebo-1] [Err] [SystemPaths.cc:378] Unable to find file with URI [model://is35_description/meshes/base_link.STL]
solidworks导出的URDF文件转到gazebo sim显示
默认导出的gazebo.launch.py
该文件适配与Gazebo classic:
import launch
import launch_ros
from ament_index_python.packages import get_package_share_directory
from launch.launch_description_sources import PythonLaunchDescriptionSource
import os
from launch.actions import TimerAction
def generate_launch_description():
# Get default path
robot_name_in_model = "is35_description"
urdf_tutorial_path = get_package_share_directory('is35_description')
default_model_path = os.path.join(
urdf_tutorial_path, 'urdf', 'is35_description.urdf')
# Read URDF file content
with open(default_model_path, 'r') as urdf_file:
robot_description = urdf_file.read()
robot_state_publisher_node = launch_ros.actions.Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'robot_description': robot_description}]
)
# Include another launch file for Gazebo
launch_gazebo = launch.actions.IncludeLaunchDescription(
PythonLaunchDescriptionSource([get_package_share_directory(
'gazebo_ros'), '/launch', '/gazebo.launch.py']),
)
# Request Gazebo to spawn the robot
spawn_entity_node = launch_ros.actions.Node(
package='gazebo_ros',
executable='spawn_entity.py',
arguments=['-topic', '/robot_description',
'-entity', robot_name_in_model])
return launch.LaunchDescription([
robot_state_publisher_node,
launch_gazebo,
# 添加延迟,确保 Gazebo 启动后再生成实体
TimerAction(
period=5.0,
actions=[spawn_entity_node]
)
])
调整为适配Gazebo sim
from launch import LaunchDescription
import launch_ros
from ament_index_python.packages import get_package_share_directory
from launch.launch_description_sources import PythonLaunchDescriptionSource
import os
from launch.actions import TimerAction
from launch.actions import IncludeLaunchDescription
from launch_ros.substitutions import FindPackageShare
from launch_ros.actions import Node
def generate_launch_description():
# Get default path
robot_name_in_model = "is35_description"
urdf_tutorial_path = get_package_share_directory('is35_description')
default_model_path = os.path.join(
urdf_tutorial_path, 'urdf', 'is35_description.urdf')
# Read URDF file content
with open(default_model_path, 'r') as urdf_file:
robot_description = urdf_file.read()
robot_state_publisher_node = launch_ros.actions.Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'robot_description': robot_description}]
)
# Include another launch file for Gazebo
launch_gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[FindPackageShare("ros_gz_sim"), "/launch/gz_sim.launch.py"]
),
launch_arguments=[("gz_args", " -r -v 3 empty.sdf")],
)
# Request Gazebo to spawn the robot
spawn_entity_node = Node(
package='ros_gz_sim',
executable='create',
output='screen',
arguments=['-topic', '/robot_description',
'-name', robot_name_in_model, '-allow_renaming', 'true'],
)
return LaunchDescription([
launch_gazebo,
robot_state_publisher_node,
# 添加延迟,确保 Gazebo 启动后再生成实体
TimerAction(
period=5.0,
actions=[spawn_entity_node]
)
])
在is35_description.urdf添加transmission
<!-- 在<joint>后添加 -->
<transmission name="joint1">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint1">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
</joint>
<actuator name="joint1_motor">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<transmission name="joint2">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint2">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
</joint>
<actuator name="joint2_motor">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<transmission name="joint3">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint3">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
</joint>
<actuator name="joint3_motor">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<transmission name="joint4">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint4">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
</joint>
<actuator name="joint4_motor">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<transmission name="joint5">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint5">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
</joint>
<actuator name="joint5_motor">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
<transmission name="joint6">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint6">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
</joint>
<actuator name="joint6_motor">
<hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
CMakeLists.txx

package.xml

修改Moveit2的导出文件
修改is35_description.ros2_control.xacro

新增is35_description.gazebo.xacro

修改is35_description.urdf.xacro

修改CMakeLists.txt
注意是is35_description路径下的CMakeLists.txt:

编译运行
colcon build
source install/local_setup.bash
ros2 launch is35_description gazebosim.launch.py
报错
warning: Using load_yaml() directly is deprecated. Use xacro.load_yaml() instead.
![图片[1] - ROS2-RViz-MoveIt-Gazebo-URDF学习笔记(六) - 鹿快](https://img.lukuai.com/blogimg/20251206/ccbbe062cfca46fdb5942d3651bbcb62.png)
修改:需要将过时的load_yaml()函数调用改为xacro.load_yaml()

[ign gazebo-1] [Err] [SystemPaths.cc:378] Unable to find file with URI [model://is35_description/meshes/base_link.STL]

问题原因:Gazebo Sim 的 resource path 里没有你的 install 目录
echo $GZ_SIM_RESOURCE_PATH | tr : '
' | grep is35_description

说明 setup.bash 并没有把 is35_description 的 share 目录写进 GZ_SIM_RESOURCE_PATH,这是 Gazebo Sim(Ignition)在 ROS 2 里的已知差异:
它只认 ament index 里声明为“gazebo_plugin”或“gazebo_model” 的条目,而普通 find_package 不会自动往里写。
临时手动 export(最快验证)
export GZ_SIM_RESOURCE_PATH=$GZ_SIM_RESOURCE_PATH:~/HuaLianCompany/aubois35_ws/install/is35_description/share
再启动 launch,mesh 若加载成功,说明路径没错。
![图片[2] - ROS2-RViz-MoveIt-Gazebo-URDF学习笔记(六) - 鹿快](https://img.lukuai.com/blogimg/20251206/b788809eecc340beb6101d80191ee367.png)
上述说明路径配置成功,且可以正常加载模型:

在 launch 文件里 动态追加路径(推荐,以后换机也不用再手动 export)
from launch import LaunchDescription
import launch_ros
from ament_index_python.packages import get_package_share_directory
from launch.launch_description_sources import PythonLaunchDescriptionSource
import os
from launch.actions import TimerAction
from launch.actions import IncludeLaunchDescription
from launch_ros.substitutions import FindPackageShare
from launch_ros.actions import Node
from launch.actions import AppendEnvironmentVariable
def generate_launch_description():
# Get default path
robot_name_in_model = "is35_description"
urdf_tutorial_path = get_package_share_directory('is35_description')
default_model_path = os.path.join(
urdf_tutorial_path, 'urdf', 'is35_description.urdf')
# 新增,注意是is35_description的父目录加进去
set_env_vars_resources = AppendEnvironmentVariable(
'GZ_SIM_RESOURCE_PATH',
os.path.join(urdf_tutorial_path,'..'))
# Read URDF file content
with open(default_model_path, 'r') as urdf_file:
robot_description = urdf_file.read()
robot_state_publisher_node = launch_ros.actions.Node(
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'robot_description': robot_description}]
)
# Include another launch file for Gazebo
launch_gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[FindPackageShare("ros_gz_sim"), "/launch/gz_sim.launch.py"]
),
launch_arguments=[("gz_args", " -r -v 3 empty.sdf")],
)
# Request Gazebo to spawn the robot
spawn_entity_node = Node(
package='ros_gz_sim',
executable='create',
output='screen',
arguments=['-topic', '/robot_description',
'-name', robot_name_in_model, '-allow_renaming', 'true'],
)
return LaunchDescription([
# 设置GZ_SIM_RESOURCE_PATH环境变量
set_env_vars_resources,
launch_gazebo,
robot_state_publisher_node,
# 添加延迟,确保 Gazebo 启动后再生成实体
TimerAction(
period=5.0,
actions=[spawn_entity_node]
)
])
















暂无评论内容