How to write URDF code

Link

<link name="my_link">  
  <!-- ===== Required: define the shape for collision (used for physics) ===== -->
  <collision>
    <geometry>      
      <!-- e.g. <box size="1 0.5 0.2"/> or <cylinder radius="0.1" length="0.5"/> -->
    </geometry>
    <!-- optional: offset the collision shape relative to the link frame -->
    <origin xyz="x y z" rpy="roll pitch yaw"/>
  </collision>

  <!-- ===== Optional: a visual mesh or primitive for RViz/Gazebo display ===== -->
  <visual>
    <geometry>
      <!-- e.g. <mesh filename="package://…/meshes/link.dae"/> -->
    </geometry>
    <origin xyz="x y z" rpy="roll pitch yaw"/>
    <material name="blue">
      <color rgba="0 0 0.8 1.0"/>
    </material>
  </visual>

  <!-- ===== Optional: mass and inertia (if omitted, Gazebo will compute with default values) ===== -->
  <inertial>
    <mass value="1.0"/>
    <inertia
      ixx="0.01" ixy="0.0" ixz="0.0"
      iyy="0.01" iyz="0.0"
      izz="0.01"/>
    <!-- optional: offset the center of mass -->
    <origin xyz="0 0 0" rpy="0 0 0"/>
  </inertial>

  <!-- ===== Gazebo-specific tweaks (optional) ===== -->
  <gazebo reference="my_link">
    <!-- e.g. <mu1>1.0</mu1> for friction, <turnGravityOff>true</turnGravityOff>, etc. -->
  </gazebo>
</link>

Joint

<?xml version="1.0"?>
<robot name="my_robot">

  <joint name="shoulder_pan_joint" type="revolute">
    <!-- Required: which two links does it connect? -->
    <parent link="base_link"/>
    <child  link="shoulder_link"/>

    <!-- Required: where is the joint frame relative to the parent link? -->
    <origin xyz="0 0 0.1" rpy="0 0 0"/>

    <!-- Required: axis of motion (for revolute/prismatic joints) -->
    <axis  xyz="0 0 1"/>

    <!-- Required for movable joints: limits on motion -->
    <limit lower="-1.57" upper="1.57"
           effort="10.0" velocity="2.0"/>

    <!-- Optional: adds viscous damping & Coulomb friction -->
    <dynamics damping="0.1" friction="0.01"/>

    <!-- Gazebo-only: tune friction, restitution, etc. -->
    <gazebo reference="shoulder_pan_joint">
      <mu1>1.0</mu1>
      <mu2>1.0</mu2>
      <turnGravityOff>true</turnGravityOff>
    </gazebo>
  </joint>

</robot>

creating a package dedicated to the robot model.

create a package for urdf files

ros2 pkg create my_robot_description --build-type ament_cmake

remove unnecessary folders

rm -r include/ src/
mkdir urdf
.
├── CMakeLists.txt
├── **launch**
│   ├── display.launch.py
│   └── display.launch.xml
├── **meshes**
├── package.xml
├── **rviz**
│   └── urdf_config.rviz
└── **urdf**
    ├── common_properties.xacro
    ├── mobile_base.xacro
    └── my_robot.urdf.xacro

update CMakeLists

install(
  DIRECTORY urdf meshes rviz launch
  DESTINATION share/${PROJECT_NAME}/
)

Update in package.xml

  <exec_depend>urdf</exec_depend>
  <exec_depend>xacro</exec_depend>
  <exec_depend>robot_state_publisher</exec_depend>
  <exec_depend>joint_state_publisher_gui</exec_depend>
  <exec_depend>rviz2</exec_depend>
  <exec_depend>ros2launch</exec_depend>