0
$\begingroup$

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]

RVIZ_Error

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:

  1. 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.
  2. 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
    ])

$\endgroup$

2 Answers 2

1
$\begingroup$

The issue is I kept all the values in axis tag under joint tag as zero even though its a joint. To correct the issue, just replace the value of axis with the direction in which you want the joint(wheel in this case) to move. I change the values in axis from:

<axis xyz="0 0 0"/>

To:

<axis xyz="0 0 1"/>

As I want the joint(wheel) to move in z axis.

$\endgroup$
0
$\begingroup$

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.

In your RViz panel, under the Global Options Tab, I see that you have selected "odom" as your fixed frame. This is why Rviz needs a transform from odom to base_link to be available. There are multiple ways to fix this, I'll put down two that are the quickest - either change the fixed frame in the global options tab, or include a static_transform_publisher to publish a static transform between base_link and odom.

ros2 run tf2_ros static_transform_publisher --help

This will show you the format that you need to pass the arguments in.

As far as I can tell, this should also take care of the second problem. It's better to verify this using the view_frames tool from the tf2_tools package.

ros2 run tf2_tools view_frames

This should yield a graph of the transforms. You can see if your odom frame is dangling, or it is properly connected to the rest of the chain.

$\endgroup$
1
  • $\begingroup$ But the wheels should be visible irrespective of what fixed frame is set to. I have another bot in which there is a base_link(blank link) and all other elements (chassis, all 4 wheels are in joint with it. In that robot, all wheels are visible dose not matter what I set fixed frame to(odom, base link, chassis). The reason I made this new bot becaue it makes more sense to attach wheels to the chassis instead of some other base link. $\endgroup$
    – Pratham
    Commented May 23 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.