鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    关于我自制了一个ROS小车的仿真模型,Gazebo车轮陷入地下

    已定时 已固定 已锁定 已移动
    动手学ROS2
    ros2 hamble gazebo 仿真 小车仿真
    2
    2
    1.1k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 1
      1402485721
      最后由 编辑

      我自制了一个ROS小车的仿真模型,Gazebo车轮陷入地下

      求大佬帮我看看

      主要问题

      在rviz中的显示为65d6063c-9168-4cc9-9138-6e8fb37d803b-image.png
      在Gazebo中的显示为:
      ddaae488-3054-4dd9-a942-065585ae192b-image.png

      相关代码

      URDF文件如下:

      <?xml version="1.0"?>
      <robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="ros_car">
      
      	<!-- 坐标系:x前、y左、z上。单位:米 -->
      	<!-- 总质量约 1.6kg;这里把轮子质量估为 0.08kg/个,底盘质量自动补齐 -->
      	<xacro:property name="total_mass" value="1.6"/>
      	<xacro:property name="wheel_mass" value="0.044"/>
      	<xacro:property name="base_mass" value="${total_mass - 4.0*wheel_mass}"/>
      
      	<!-- 车体长方体:150*200*100mm。按常见约定我取:长度x=200mm,宽度y=150mm,高度z=100mm -->
      	<!-- 如果你确实想 x=150,y=200,交换 base_length/base_width 即可 -->
      	<xacro:property name="base_length" value="0.200"/>
      	<xacro:property name="base_width" value="0.150"/>
      	<xacro:property name="base_height" value="0.100"/>
      
      	<!-- 麦轮:直径60mm,宽24.5mm -->
      	<xacro:property name="wheel_radius" value="0.030"/>
      	<xacro:property name="wheel_width" value="0.0245"/>
      
      	<!-- 轮中心相对 base_link:|x|=60mm, |y|=87.5mm -->
      	<xacro:property name="wheel_x" value="0.060"/>
      	<xacro:property name="wheel_y" value="0.0875"/>
      
      	<!-- 为了Gazebo不穿地:轮中心相对 base_link 的 z 取 -base_height/2 (= -50mm) -->
      	<!-- 如果你只想严格按你描述(z=0),把下面改成 0 -->
      	<xacro:property name="wheel_z_in_base" value="${-base_height/2.0}"/>
      
      	<!-- 传感器安装(相对 base_link) -->
      	<!-- A1:(-40mm, 0, 65mm);D435i:(80mm, 0, 62.5mm) -->
      	<xacro:property name="lidar_x" value="-0.040"/>
      	<xacro:property name="lidar_y" value="0.000"/>
      	<xacro:property name="lidar_z" value="0.065"/>
      
      	<xacro:property name="camera_x" value="0.080"/>
      	<xacro:property name="camera_y" value="0.000"/>
      	<xacro:property name="camera_z" value="0.0625"/>
      
      	<!-- D435i 形状:100*25*25mm -->
      	<xacro:property name="camera_box_x" value="0.100"/>
      	<xacro:property name="camera_box_y" value="0.025"/>
      	<xacro:property name="camera_box_z" value="0.025"/>
      
      	<!-- A1 底座:100*100*30mm;雷达本体:圆柱直径70mm,高25mm -->
      	<xacro:property name="lidar_base_xy" value="0.100"/>
      	<xacro:property name="lidar_base_z" value="0.030"/>
      	<xacro:property name="lidar_cyl_d" value="0.070"/>
      	<xacro:property name="lidar_cyl_z" value="0.025"/>
      
      	<!-- ================= 惯量宏(够用,后续可精修) ================= -->
      	<xacro:macro name="inertial_box" params="m x y z">
      		<inertial>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<mass value="${m}"/>
      			<inertia ixx="${(m/12.0) * (y*y + z*z)}" iyy="${(m/12.0) * (x*x + z*z)}" izz="${(m/12.0) * (x*x + y*y)}" ixy="0" ixz="0" iyz="0"/>
      		</inertial>
      	</xacro:macro>
      
      	<xacro:macro name="inertial_cylinder_y" params="m r h">
      		<inertial>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<mass value="${m}"/>
      			<inertia ixx="${(m/12.0) * (3*r*r + h*h)}" iyy="${(m/2.0)  * (r*r)}" izz="${(m/12.0) * (3*r*r + h*h)}" ixy="0" ixz="0" iyz="0"/>
      		</inertial>
      	</xacro:macro>
      
      	<!-- ================= TF 根:base_footprint 在地面投影点 ================= -->
      	<link name="base_footprint"/>
      
      	<!-- base_link 放在底盘几何中心;为了让轮子落在地面,base_link 高度=轮半径+底盘高度/2 -->
      	<joint name="base_footprint_to_base_link" type="fixed">
      		<origin xyz="0 0 ${wheel_radius + base_height/2.0}" rpy="0 0 0"/>
      		<parent link="base_footprint"/>
      		<child link="base_link"/>
      	</joint>
      
      	<!-- ================= 底盘(简单长方体) ================= -->
      	<link name="base_link">
      		<xacro:inertial_box m="${base_mass}" x="${base_length}" y="${base_width}" z="${base_height}"/>
      
      		<visual>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<box size="${base_length} ${base_width} ${base_height}"/>
      			</geometry>
      			<material name="Gray">
      				<color rgba="0.6 0.6 0.6 1.0"/>
      			</material>
      		</visual>
      
      		<collision>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<box size="${base_length} ${base_width} ${base_height}"/>
      			</geometry>
      		</collision>
      	</link>
      
      	<!-- ================= 轮子(四个连续关节) ================= -->
      	<xacro:macro name="wheel" params="prefix x y">
      		<link name="${prefix}_wheel_link">
      			<xacro:inertial_cylinder_y m="${wheel_mass}" r="${wheel_radius}" h="${wheel_width}"/>
      
      			<!-- URDF cylinder 默认沿 z 轴;转 90° 让它沿 y 轴(轮子自转轴是 y) -->
      			<visual>
      				<origin xyz="0 0 0" rpy="1.57079632679 0 0"/>
      				<geometry>
      					<cylinder radius="${wheel_radius}" length="${wheel_width}"/>
      				</geometry>
      				<material name="Black">
      					<color rgba="0.1 0.1 0.1 1.0"/>
      				</material>
      			</visual>
      
      			<collision>
      				<origin xyz="0 0 0" rpy="1.57079632679 0 0"/>
      				<geometry>
      					<cylinder radius="${wheel_radius}" length="${wheel_width}"/>
      				</geometry>
      			</collision>
      		</link>
      
      		<!-- 轮子关节的坐标是“相对 base_link”,x/y 用你给的,z 用 wheel_z_in_base -->
      		<joint name="${prefix}_wheel_joint" type="continuous">
      			<origin xyz="${x} ${y} ${wheel_z_in_base}" rpy="0 0 0"/>
      			<parent link="base_link"/>
      			<child link="${prefix}_wheel_link"/>
      			<axis xyz="0 1 0"/>
      			<dynamics damping="0.2" friction="0.2"/>
      		</joint>
      	</xacro:macro>
      
      	<!-- LF 左前、RF 右前、LR 左后、RR 右后 -->
      	<xacro:wheel prefix="lf" x="${ wheel_x}" y="${ wheel_y}"/>
      	<xacro:wheel prefix="rf" x="${ wheel_x}" y="${-wheel_y}"/>
      	<xacro:wheel prefix="lr" x="${-wheel_x}" y="${ wheel_y}"/>
      	<xacro:wheel prefix="rr" x="${-wheel_x}" y="${-wheel_y}"/>
      
      	<!-- ================= D435i(用长方体表示,放在 camera_link) ================= -->
      	<link name="camera_link">
      		<visual>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<box size="${camera_box_x} ${camera_box_y} ${camera_box_z}"/>
      			</geometry>
      			<material name="Blue">
      				<color rgba="0.2 0.3 0.9 1.0"/>
      			</material>
      		</visual>
      		<collision>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<box size="${camera_box_x} ${camera_box_y} ${camera_box_z}"/>
      			</geometry>
      		</collision>
      	</link>
      
      	<joint name="camera_joint" type="fixed">
      		<origin xyz="${camera_x} ${camera_y} ${camera_z}" rpy="0 0 1.57079632679"/>
      		<parent link="base_link"/>
      		<child link="camera_link"/>
      	</joint>
      
      	<!-- 可选:相机光学坐标系(ROS常用约定:z向前,x向右,y向下) -->
      	<link name="camera_optical_frame"/>
      	<joint name="camera_optical_joint" type="fixed">
      		<origin xyz="0 0 0" rpy="-1.57079632679 0 -1.57079632679"/>
      		<parent link="camera_link"/>
      		<child link="camera_optical_frame"/>
      	</joint>
      
      	<!-- ================= A1 雷达(雷达本体圆柱是 lidar_link;底座单独做成 child link) ================= -->
      	<link name="lidar_link">
      		<visual>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<cylinder radius="${lidar_cyl_d/2.0}" length="${lidar_cyl_z}"/>
      			</geometry>
      			<material name="White">
      				<color rgba="0.9 0.9 0.9 1.0"/>
      			</material>
      		</visual>
      		<collision>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<cylinder radius="${lidar_cyl_d/2.0}" length="${lidar_cyl_z}"/>
      			</geometry>
      		</collision>
      	</link>
      
      	<joint name="lidar_joint" type="fixed">
      		<origin xyz="0 0 ${lidar_cyl_z/2.0 + lidar_base_z/2.0}" rpy="0 0 0"/>
      		<parent link="lidar_base_link"/>
      		<child link="lidar_link"/>
      	</joint>
      
      	<!-- 底座放在雷达圆柱正下方:偏移 z = -(圆柱半高 + 底座半高) -->
      	<joint name="lidar_base_joint" type="fixed">
      		<origin xyz="${lidar_x} ${lidar_y} ${lidar_z}" rpy="0 0 0"/>
      		<parent link="base_link"/>
      		<child link="lidar_base_link"/>
      	</joint>
      
      	<link name="lidar_base_link">
      		<visual>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<box size="${lidar_base_xy} ${lidar_base_xy} ${lidar_base_z}"/>
      			</geometry>
      			<material name="DarkGray">
      				<color rgba="0.25 0.25 0.25 1.0"/>
      			</material>
      		</visual>
      		<collision>
      			<origin xyz="0 0 0" rpy="0 0 0"/>
      			<geometry>
      				<box size="${lidar_base_xy} ${lidar_base_xy} ${lidar_base_z}"/>
      			</geometry>
      		</collision>
      	</link>
      
      	<!-- IMU 坐标系(先给一个标准 link,后续你接真IMU/仿真IMU都方便) -->
      	<link name="imu_link"/>
      	<joint name="imu_joint" type="fixed">
      		<origin xyz="0 0 0" rpy="0 0 0"/>
      		<parent link="base_link"/>
      		<child link="imu_link"/>
      	</joint>
      
      </robot>
      

      gazebo的launch文件如下:

      from launch import LaunchDescription
      from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
      from launch.launch_description_sources import PythonLaunchDescriptionSource
      from launch.substitutions import Command, LaunchConfiguration
      from launch_ros.actions import Node
      from ament_index_python.packages import get_package_share_directory
      import os
      
      
      def generate_launch_description():
          use_sim_time = LaunchConfiguration("use_sim_time")
          world = LaunchConfiguration("world")
          gui = LaunchConfiguration("gui")
          verbose = LaunchConfiguration("verbose")
      
          # 你的 xacro
          desc_pkg = get_package_share_directory("ros_car_description")
          xacro_file = os.path.join(desc_pkg, "urdf", "ros_car.urdf.xacro")
      
          # Gazebo Classic 的官方 launch(来自 gazebo_ros)
          gazebo_ros_pkg = get_package_share_directory("gazebo_ros")
          gazebo_launch = os.path.join(gazebo_ros_pkg, "launch", "gazebo.launch.py")
      
          # 获取worlds文件夹路径
          worlds_dir = os.path.join(desc_pkg, "worlds")
          default_world = os.path.join(worlds_dir, "custom_room.world")
      
          # robot_description
          robot_description = Command(["xacro", " ", xacro_file])
      
          return LaunchDescription(
              [
                  DeclareLaunchArgument("use_sim_time", default_value="true"),
                  # world 参数现在默认指向 worlds 文件夹中的 custom_room.world
                  DeclareLaunchArgument("world", default_value=default_world),
                  DeclareLaunchArgument("gui", default_value="true"),
                  DeclareLaunchArgument("verbose", default_value="false"),
                  # 启动 Gazebo Classic
                  IncludeLaunchDescription(
                      PythonLaunchDescriptionSource(gazebo_launch),
                      launch_arguments={
                          "world": world,
                          "gui": gui,
                          "verbose": verbose,
                      }.items(),
                  ),
                  # 发布 TF(RViz / TF 树用)
                  Node(
                      package="robot_state_publisher",
                      executable="robot_state_publisher",
                      parameters=[
                          {
                              "use_sim_time": use_sim_time,
                              "robot_description": robot_description,
                          }
                      ],
                      output="screen",
                  ),
                  # 没有 ros2_control 的情况下,让关节至少有默认 0 值(轮子连续关节不至于缺 joint_states)
                  Node(
                      package="joint_state_publisher",
                      executable="joint_state_publisher",
                      parameters=[{"use_sim_time": use_sim_time}],
                      output="screen",
                  ),
                  # 把模型从 robot_description 生成到 Gazebo 里
                  # -z 给个高度避免初始穿地(根据你模型尺寸 0.2 基本够)
                  Node(
                      package="gazebo_ros",
                      executable="spawn_entity.py",
                      arguments=[
                          "-entity",
                          "ros_car",
                          "-topic",
                          "robot_description",
                          "-x",
                          "0",
                          "-y",
                          "0",
                          "-z",
                          "0.2",
                      ],
                      output="screen",
                  ),
              ]
          )
      

      rviz2的launch文件如下:

      from launch import LaunchDescription
      from launch.substitutions import Command
      from launch_ros.actions import Node
      from ament_index_python.packages import get_package_share_directory
      import os
      
      
      def generate_launch_description():
          pkg = get_package_share_directory("ros_car_description")
          xacro_file = os.path.join(pkg, "urdf", "ros_car.urdf.xacro")
          robot_description = {"robot_description": Command(["xacro", " ", xacro_file])}
      
          rviz_config = os.path.join(pkg, "config", "display_robot.rviz")
      
          return LaunchDescription(
              [
                  Node(
                      package="robot_state_publisher",
                      executable="robot_state_publisher",
                      parameters=[robot_description],
                      output="screen",
                  ),
                  Node(
                      package="joint_state_publisher",
                      executable="joint_state_publisher",
                      output="screen",
                  ),
                  Node(
                      package="rviz2",
                      executable="rviz2",
                      arguments=["-d", rviz_config],
                      output="screen",
                  ),
              ]
          )
      
      3 1 条回复 最后回复 回复 引用 0
      • 3
        374200573 0 @1402485721
        最后由 编辑

        @1402485721 gazebo 的kp kd 太小

        1 条回复 最后回复 回复 引用 0
        • 第一个帖子
          最后一个帖子
        皖ICP备16016415号-7
        Powered by NodeBB | 鱼香ROS