In rviz I am getting error:
- No Transform from [front_left_link] to [odom]
- No Transform from [front_right_link] to [odom]
- No Transform from [rear_left_link] to [odom]
- No Transform from [rear_right_link] to [odom]
The following links are available:
- base_link --> Blank link
- chassis_link --> robot frame (attached to base_link)
- front_left_link --> Front Left Wheel (attached to chassis)
- front_right_link --> Front Right Wheel (attached to chassis)
- rear_left_link --> Rear Left Wheel (attached to chassis)
- rear_right_link --> Rear Right Wheel (attached to chassis)
Now I want the transform from wheels to chassis_link to be published instead of wheels to odom. According to my understanding, "robot_state_publisher" automatically publishes these transform using the URDF and I dont need to interfere.
Question:
- Why rviz is looking for wheels to odom transform? where did i mentioned that? According to me the transform should be published according to joints in URDF.
- Why are the required transforms "wheel to chassis_link" being not published even though robot state publisher is active and is publishing transforms from base_link to chassis_link.
URDF
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="inertial_macros.xacro" />
<!-- Colors -->
<material name="purple">
<color rgba="0.5 0 0.5 1"/>
</material>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
<!-- Chassis Properties -->
<xacro:property name="chassis_width" value="0.6"/> <!-- 6 meter = 600 cm -->
<xacro:property name="chassis_height" value="0.6"/> <!-- 6 meter = 600 cm -->
<xacro:property name="chassis_depth" value="0.02"/> <!-- 0.02meter = 2 cm -->
<xacro:property name="chassis_mass" value="1"/> <!-- 1 kg -->
<!-- Wheel Properties -->
<xacro:property name="wheel_radius" value="0.05"/>
<xacro:property name="wheel_width" value="0.02"/>
<xacro:property name="wheel_mass" value="1"/>
<!-- Wheel Macro -->
<xacro:macro name="wheel_macro" params="wheel_name wheel_color mu1 mu2"> <!-- mu max_val = 1 (max friction) min_val = 0(min friction) -->
<link name="${wheel_name}">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="${wheel_width}" radius="${wheel_radius}" />
</geometry>
<material name="white"/>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="${wheel_width}" radius="${wheel_radius}" />
</geometry>
</collision>
<xacro:inertial_cylinder mass="${wheel_mass}" length="${wheel_width}" radius="${wheel_radius}">
<origin xyz="0 0 0" rpy="0 0 0"/>
</xacro:inertial_cylinder>
</link>
<gazebo reference="${wheel_name}">
<!-- <material>${wheel_color}</material> -->
<material>Gazebo/Yellow</material>
<mu1 value="${mu1}"/>
<mu2 value="${mu2}"/>
</gazebo>
</xacro:macro>
<!-- BASE LINK -->
<link name="base_link">
</link>
<!-- Chassis Link -->
<joint name="chassis_joint" type="fixed">
<parent link="base_link"/>
<child link="chassis_link"/>
<origin xyz="0 0 0.06"/> <!-- xyz = 0, 0, height_to_raise + chassis_depth/2 -->
</joint>
<link name="chassis_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="${chassis_width} ${chassis_height} ${chassis_depth}"/>
</geometry>
<material name="purple"/>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="${chassis_width} ${chassis_height} ${chassis_depth}"/>
</geometry>
</collision>
<xacro:inertial_box mass="${chassis_mass}" x="${chassis_width}" y="${chassis_height}" z="${chassis_depth}">
<origin xyz="0 0 0" rpy="0 0 0"/>
</xacro:inertial_box>
</link>
<gazebo reference="chassis_link">
<material>Gazebo/Purple</material>
</gazebo>
<!-- Front Left Wheel -->
<!-- <joint name="front_left_joint" type="continuous"> -->
<joint name="dummy_left_joint" type="continuous">
<parent link="chassis_link" />
<child link="front_left_link" />
<origin xyz="0.3 -0.3 0" rpy="0 0 0" />
<axis xyz="0 0 0"/>
</joint>
<xacro:wheel_macro wheel_name="front_left_link" wheel_color="Gazebo/Yellow" mu1="1.0" mu2="1.0"/>
<!-- Front Right Wheel -->
<!-- <joint name="front_right_joint" type="continuous"> -->
<joint name="dummy_right_joint" type="continuous">
<parent link="chassis_link" />
<child link="front_right_link" />
<origin xyz="0.3 0.3 0" rpy="0 0 0" />
<axis xyz="0 0 0"/>
</joint>
<xacro:wheel_macro wheel_name="front_right_link" wheel_color="Gazebo/Yellow" mu1="1.0" mu2="1.0"/>
<!-- Rear Left Wheel -->
<!-- <joint name="rear_left_joint" type="continuous"> -->
<joint name="left_wheel_joint" type="continuous">
<parent link="chassis_link" />
<child link="rear_left_link" />
<origin xyz="-0.3 -0.3 0" rpy="0 0 0" />
<axis xyz="0 0 0"/>
</joint>
<xacro:wheel_macro wheel_name="rear_left_link" wheel_color="Gazebo/Yellow" mu1="1.0" mu2="1.0"/>
<!-- Rear Right Wheel -->
<!-- <joint name="rear_right_joint" type="continuous"> -->
<joint name="right_wheel_joint" type="continuous">
<parent link="chassis_link" />
<child link="rear_right_link" />
<origin xyz="-0.3 0.3 0" rpy="0 0 0" />
<axis xyz="0 0 0"/>
</joint>
<xacro:wheel_macro wheel_name="rear_right_link" wheel_color="Gazebo/Yellow" mu1="1.0" mu2="1.0"/>
</robot>
Launch File - rsp.launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.substitutions import LaunchConfiguration
from launch.actions import DeclareLaunchArgument
from launch_ros.actions import Node
import xacro
def generate_launch_description():
# Check if we're told to use sim time
use_sim_time = LaunchConfiguration('use_sim_time')
# Process the URDF file
pkg_path = os.path.join(get_package_share_directory('test_bot'))
xacro_file = os.path.join(pkg_path,'description','robot.urdf.xacro')
robot_description_config = xacro.process_file(xacro_file)
# Create a robot_state_publisher node
params = {'robot_description': robot_description_config.toxml(), 'use_sim_time': use_sim_time}
node_robot_state_publisher = Node(
package='robot_state_publisher',
executable='robot_state_publisher',
output='screen',
parameters=[params]
)
# Launch!
return LaunchDescription([
DeclareLaunchArgument(
'use_sim_time',
default_value='false',
description='Use sim time if true'),
node_robot_state_publisher
])
Launch File - launch_sim.launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
def generate_launch_description():
package_name='test_bot'
rsp = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory(package_name),'launch','rsp.launch.py'
)]), launch_arguments={'use_sim_time': 'true'}.items()
)
# Include the Gazebo launch file, provided by the gazebo_ros package
gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource([os.path.join(
get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py')]),
)
# Run the spawner node from the gazebo_ros package. The entity name doesn't really matter if you only have a single robot.
spawn_entity = Node(package='gazebo_ros', executable='spawn_entity.py',
arguments=['-topic', 'robot_description',
'-entity', 'nice_bot'],
output='screen')
# Ros2 Controller
diff_drive_spawner = Node(
package="controller_manager",
executable="spawner",
#arguments=["mec_cont"],
arguments=["diff_cont"],
)
joint_broad_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["joint_broad"],
)
# Launch them all!
return LaunchDescription([
rsp,
gazebo,
spawn_entity,
diff_drive_spawner,
joint_broad_spawner
])