Exploring ROS with a 2 Wheeled Robot #3 : URDF of a Laser Scan

Exploring ROS with a 2 Wheeled Robot #3 : URDF of a Laser Scan

Hello ROS Developers!

In this post, we start summarizing our YouTube video series called “Exploring ROS with a 2 wheeled Robot”. That’s the part #03 and we hope to help you learning this amazing content by another media, our blog posts. Let’s start!

In the last post, we worked a while with XACROs, in order to simplify our robot model. And now we are going to attach a Laser Scan sensor to our model!

If you don’t have a ROSJect with the previous tutorial, just make a copy of this one, which is the source we are about to start from. Let’s go!

The first modification we’ll do goes to the file ~/simulation_ws/src/m2wr_description/urdf/m2wr.xacro, just after the chassis link (should be at line 54)

  <link name="sensor_laser">
    <inertial>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <mass value="1" />
        <xacro:cylinder_inertia mass="1" r="0.05" l="0.1" />
    </inertial>

    <visual>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <geometry>
        <cylinder radius="0.05" length="0.1"/>
        </geometry>
        <material name="white" />
    </visual>

    <collision>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
        <cylinder radius="0.05" length="0.1"/>
        </geometry>
    </collision>
    </link>

    <joint name="joint_sensor_laser" type="fixed">
    <origin xyz="0.15 0 0.05" rpy="0 0 0"/>
    <parent link="link_chassis"/>
    <child link="sensor_laser"/>
  </joint>

Check that we have a new macro being called, a function for generatin cylinder description for URDF. We have added a new link, to represent the laser scan, as every link, it contains inertial, visual and collision attributes. Finally, a joint to bind it to the root link, the chassis.

In order to have it working, let’s go to the second file: ~/simulation_ws/src/m2wr_description/urdf/macros.xacro. At line 36, lets add the following code (to describe our cylinder macro):

<macro name="cylinder_inertia" params="mass r l">
  <inertia  ixx="${mass*(3*r*r+l*l)/12}" ixy = "0" ixz = "0"
            iyy="${mass*(3*r*r+l*l)/12}" iyz = "0"
            izz="${mass*(r*r)/2}" />
</macro>

Let’s check it in RViz!

Go to a web shell and execute:

user:~$ roslaunch m2wr_description rviz.launch

Open the graphical tools, you must have something like this:

So we have a white part on the robot that represents a laser scan!

Now.. Let’s make it a REAL laser scan (in the simulation, I mean =D )

Go to the last file we are going to modify: ~/simulation_ws/src/m2wr_description/urdf/m2wr.gazebo

Place the code below just after the closing tag of the diff_drive plugin:

  <gazebo reference="sensor_laser">
    <sensor type="ray" name="head_hokuyo_sensor">
      <pose>0 0 0 0 0 0</pose>
      <visualize>false</visualize>
      <update_rate>20</update_rate>
      <ray>
        <scan>
          <horizontal>
            <samples>720</samples>
            <resolution>1</resolution>
            <min_angle>-1.570796</min_angle>
            <max_angle>1.570796</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.10</min>
          <max>10.0</max>
          <resolution>0.01</resolution>
        </range>
        <noise>
          <type>gaussian</type>
          <mean>0.0</mean>
          <stddev>0.01</stddev>
        </noise>
      </ray>
      <plugin name="gazebo_ros_head_hokuyo_controller" filename="libgazebo_ros_laser.so">
        <topicName>/m2wr/laser/scan</topicName>
        <frameName>sensor_laser</frameName>
      </plugin>
    </sensor>
  </gazebo>

Take a look at the code. Notice that we are describer there the frameName and topicName. They are important in order to visualize it in RViz and, of course, program the robot.

Other important attributes you can tune for your application are: rangescan and update_rate. Feel free to explore it. Don’t miss the official documentation from gazebo!

Great, let’s launch a simulation with the robot and its Real Laser Scan! I’ll start a world of my choice, the one barrels, so I can check the laser readings easily. You can play with other worlds further. Go to the simulations tab and choose one:

Now, spawn the robot from the terminal:

user:~$ roslaunch m2wr_description spawn.launch

And check the robot there:

You can “echo” the topic /m2wr/laser/scan to check data coming from the laser. Of course it won’t make much sense in the terminal. So let’s check in RViz. Once more to the terminal, run:

user:~$ roslaunch m2wr_description rviz.launch

Configure RViz to visualize the RobotModel and the LaserScan (check the following image):

In order to compare, let’s check the robot and world obstacles in gazebo:

Amazing! Isn’t it?

Don’t forget to leave a comment, ask for help your suggest your ideas!

If something went wrong in your ROSJect during the post reading, you can copy mine by clicking here, it’s ready to use!

In the next post, we will start using the data from the LaserScan. Let’s make the robot navigate around the world!

 

Cheers!

Exploring ROS with a 2 Wheeled Robot #2: URDF Macros (XACRO)

Exploring ROS with a 2 Wheeled Robot #2: URDF Macros (XACRO)

XACROs

In this tutorial, we are going to explore the macros for URDF files, using XACRO files. At the end of this tutorial, we will have the same model organized in different files, in an organized way.

STEP 1

With the first part done we have a simple robot description working. Now.. Let’s organize the different parts of the robot in many files. We are going to do that using XACRO.

We started already creating a .xacro file, but we haven’t used the functions XACRO provides. This is what we are going to achieve to the end of this post.

First step: we are not going to only READ the robot description file, instead we’ll CONVERT the .xacro file into a .urdf using python command

in our launch file. Beginning from ~/simulation_ws/src/m2wr_description/rviz.launch, we have to replace line number 4:

From
<param name="robot_description" command="cat '$(find m2wr_description)/urdf/m2wr.xacro'"/>

to

<param name="robot_description" command="$(find xacro)/xacro.py '$(find m2wr_description)/urdf/m2wr.xacro'"/>

You can launch RViz and load the model as usual. The only difference is in the backgrounds, we are rendering URDF model from xacro commands.

Do the same for ~/simulation_ws/src/m2wr_description/spawn.launchline number 4.

So.. what now? I have URDF being rendered by xacro commands. Let’s split our robot model into different files!

STEP 2

I’ll start creating a new file called ~/simulation_ws/src/m2wr_description/urdf/materials.xacro. Let’s cut and paste the following code from m2wr.xacro to materials.xacro

From m2wr.xacro, cut it:

<material name="black">
    <color rgba="0.0 0.0 0.0 1.0"/>
  </material>
  <material name="blue">
    <color rgba="0.203125 0.23828125 0.28515625 1.0"/>
  </material>
  <material name="green">
    <color rgba="0.0 0.8 0.0 1.0"/>
  </material>
  <material name="grey">
    <color rgba="0.2 0.2 0.2 1.0"/>
  </material>
  <material name="orange">
    <color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
  </material>
  <material name="brown">
    <color rgba="0.870588235294 0.811764705882 0.764705882353 1.0"/>
  </material>
  <material name="red">
    <color rgba="0.80078125 0.12890625 0.1328125 1.0"/>
  </material>
  <material name="white">
    <color rgba="1.0 1.0 1.0 1.0"/>
  </material>

And create a new file materials.xacro, beginning with XML definition of file and a <robot> tag:

<?xml version="1.0" ?>
<robot>
  <material name="black">
    <color rgba="0.0 0.0 0.0 1.0"/>
  </material>
  <material name="blue">
    <color rgba="0.203125 0.23828125 0.28515625 1.0"/>
  </material>
  <material name="green">
    <color rgba="0.0 0.8 0.0 1.0"/>
  </material>
  <material name="grey">
    <color rgba="0.2 0.2 0.2 1.0"/>
  </material>
  <material name="orange">
    <color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
  </material>
  <material name="brown">
    <color rgba="0.870588235294 0.811764705882 0.764705882353 1.0"/>
  </material>
  <material name="red">
    <color rgba="0.80078125 0.12890625 0.1328125 1.0"/>
  </material>
  <material name="white">
    <color rgba="1.0 1.0 1.0 1.0"/>
  </material>
</robot>

Great!

STEP 3

Let’s create one more file to handle gazebo stuff. It’s gonna be called: m2wr.gazebo and contains all gazebo properties we current have just below the include of materials.xacro. Our file ~/simulation_ws/src/m2wr_description/urdf/m2wr.gazebo is gonna be like:

<?xml version="1.0" ?>
<robot>
  <gazebo reference="link_chassis">
    <material>Gazebo/Orange</material>
  </gazebo>
  <gazebo reference="link_left_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>
  <gazebo reference="link_right_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>

  <gazebo>
    <plugin filename="libgazebo_ros_diff_drive.so" name="differential_drive_controller">
      <legacyMode>false</legacyMode>
      <alwaysOn>true</alwaysOn>
      <updateRate>20</updateRate>
      <leftJoint>joint_left_wheel</leftJoint>
      <rightJoint>joint_right_wheel</rightJoint>
      <wheelSeparation>0.2</wheelSeparation>
      <wheelDiameter>0.2</wheelDiameter>
      <torque>0.1</torque>
      <commandTopic>cmd_vel</commandTopic>
      <odometryTopic>odom</odometryTopic>
      <odometryFrame>odom</odometryFrame>
      <robotBaseFrame>link_chassis</robotBaseFrame>
    </plugin>
  </gazebo>
</robot>

STEP 4

Great! Let’s create one more file, in order to simplify the way we are defining the wheels of our robot!

Create a new file ~/simulation_ws/src/m2wr_description/urdf/macros.xacro. And fasten your seat belt because this part will contain some tricks and formulas to make things more dynamic!

Why is that? The robots has 2 wheels, the description of both of them are the same, except for their names and direction. We are going to create a MACRO that fills these properties (for joints and links) according to arguments we are going to pass from m2wr.xacro to macros.xacro.

Our macros.xacro will be like:

<?xml version="1.0"?>
<robot>
    <macro name="link_wheel" params="name">
        <link name="${name}">
            <inertial>
              <mass value="0.2"/>
              <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
              <inertia ixx="0.000526666666667" ixy="0" ixz="0" iyy="0.000526666666667" iyz="0" izz="0.001"/>
            </inertial>
            <collision name="link_right_wheel_collision">
              <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
              <geometry>
                <cylinder length="0.04" radius="0.1"/>
              </geometry>
            </collision>
            <visual name="${name}_visual">
              <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
              <geometry>
                <cylinder length="0.04" radius="0.1"/>
              </geometry>
            </visual>
        </link>
    </macro>

    <macro name="joint_wheel" params="name child origin_xyz">
      <joint name="${name}" type="continuous">
        <origin rpy="0 0 0" xyz="${origin_xyz}"/>
        <child link="${child}"/>
        <parent link="link_chassis"/>
        <axis rpy="0 0 0" xyz="0 1 0"/>
        <limit effort="10000" velocity="1000"/>
        <joint_properties damping="1.0" friction="1.0"/>
      </joint>
    </macro>
</robot>

STEP 5

Finally, our main file m2wr.xacro will be summarized to this:

<?xml version="1.0" ?>
<robot name="m2wr" xmlns:xacro="http://www.ros.org/wiki/xacro">

  <xacro:include filename="$(find m2wr_description)/urdf/materials.xacro" />
  <xacro:include filename="$(find m2wr_description)/urdf/m2wr.gazebo" />
  <xacro:include filename="$(find m2wr_description)/urdf/macros.xacro" />

  <link name="link_chassis">
    <!-- pose and inertial -->
    <pose>0 0 0.1 0 0 0</pose>
    <inertial>
      <mass value="5"/>
      <origin rpy="0 0 0" xyz="0 0 0.1"/>
      <inertia ixx="0.0395416666667" ixy="0" ixz="0" iyy="0.106208333333" iyz="0" izz="0.106208333333"/>
    </inertial>
    <!-- body -->
    <collision name="collision_chassis">
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
    </collision>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
      <material name="blue"/>
    </visual>
    <!-- caster front -->
    <collision name="caster_front_collision">
      <origin rpy=" 0 0 0" xyz="0.35 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
      <surface>
        <friction>
          <ode>
            <mu>0</mu>
            <mu2>0</mu2>
            <slip1>1.0</slip1>
            <slip2>1.0</slip2>
          </ode>
        </friction>
      </surface>
    </collision>
    <visual name="caster_front_visual">
      <origin rpy=" 0 0 0" xyz="0.2 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
    </visual>
  </link>

  <xacro:link_wheel name="link_right_wheel" />
  <xacro:joint_wheel name="joint_right_wheel" child="link_right_wheel" origin_xyz="-0.05 0.15 0" />

  <xacro:link_wheel name="link_left_wheel" />
  <xacro:joint_wheel name="joint_left_wheel" child="link_left_wheel" origin_xyz="-0.05 -0.15 0" />
</robot>

We didn’t create a macro for the link link_chassis because we would have the almost the same amount of code, after all we have a single piece using that description. Of course, you can put it into a different file, in order to have your main description file having only includes of different pieces.

At this point, you must be able to launch an empty simulation and spawn the robot. The same applies to visualize the robot in RViz. We don’t have anything different in the results, but a much better to maintain code!

If you didn’t reach this point, you can copy the original project using this link: http://www.rosject.io/l/90f1026/

In this next tutorial, we’re going to insert a laser scan sensor to the robot.

[irp posts=”13043″ name=”Exploring ROS with a 2 Wheeled Robot #3 : URDF of a Laser Scan”]

Don’t forget! If you like this kind of post, participate! Comment or share it! Let us know your opinion!

Cheers!

Related courses:

Exploring ROS using a 2 Wheeled Robot #1: Basics of Robot Modeling using URDF

Exploring ROS using a 2 Wheeled Robot #1: Basics of Robot Modeling using URDF

Explore the basics of robot modeling using the URDF

In this tutorial, we’re going to explore the basics of robot modeling using the Unified Robot Description Format (URDF). At the end of this tutorial, we will have a model ready and running in Gazebo simulator. Let’s start!

STEP 1

First of all, this project was created to help ROS beginners to understand the main tools ROS provides using a quite simple kind of robot. In order to do that, we are going to use ROSDS (ROS Development Studio). In this first part, we are going to create a robot model, visualize it in RViz and spawn it into a gazebo world.

Go to this page to start using it! Create a new ROSject and open it. That’s our development environment or ROSDS desktop:

STEP 2

Let’s start creating our package, inside of simulation_ws/src:

user:~$ cd ~/simulation_ws/src
user:~$ catkin_create_pkg m2wr_description urdf

The first we are gonna do it to create the robot description file. We are using a XACRO file. It’s a big file in this first moment, we will explain how to break it into different ones in the next posts, but for now let’s keep it like that. It’s shown only the beginning of the file. See the full content here.

STEP 3

Create a new folder urdf inside of ~/simulation_ws/src/m2wr_description and paste the robot description to a new file: ~/simulation_ws/src/m2wr_description/urdf/m2wr.xacro

<?xml version="1.0" ?>
<robot name="m2wr" xmlns:xacro="http://www.ros.org/wiki/xacro">
  <material name="black">
    <color rgba="0.0 0.0 0.0 1.0"/>
  </material>
  <material name="blue">
    <color rgba="0.203125 0.23828125 0.28515625 1.0"/>
  </material>
  <material name="green">
    <color rgba="0.0 0.8 0.0 1.0"/>
  </material>
  <material name="grey">
    <color rgba="0.2 0.2 0.2 1.0"/>
  </material>
  <material name="orange">
    <color rgba="1.0 0.423529411765 0.0392156862745 1.0"/>
  </material>
  <material name="brown">
    <color rgba="0.870588235294 0.811764705882 0.764705882353 1.0"/>
  </material>
  <material name="red">
    <color rgba="0.80078125 0.12890625 0.1328125 1.0"/>
  </material>
  <material name="white">
    <color rgba="1.0 1.0 1.0 1.0"/>
  </material>
  
  <gazebo reference="link_chassis">
    <material>Gazebo/Orange</material>
  </gazebo>
  <gazebo reference="link_left_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>
  <gazebo reference="link_right_wheel">
    <material>Gazebo/Blue</material>
  </gazebo>
  
  <gazebo>
    <plugin filename="libgazebo_ros_diff_drive.so" name="differential_drive_controller">
      <legacyMode>false</legacyMode>
      <alwaysOn>true</alwaysOn>
      <updateRate>20</updateRate>
      <leftJoint>joint_left_wheel</leftJoint>
      <rightJoint>joint_right_wheel</rightJoint>
      <wheelSeparation>0.2</wheelSeparation>
      <wheelDiameter>0.2</wheelDiameter>
      <torque>0.1</torque>
      <commandTopic>cmd_vel</commandTopic>
      <odometryTopic>odom</odometryTopic>
      <odometryFrame>odom</odometryFrame>
      <robotBaseFrame>link_chassis</robotBaseFrame>
    </plugin>
  </gazebo>
  
  <link name="link_chassis">
    <!-- pose and inertial -->
    <pose>0 0 0.1 0 0 0</pose>
    <inertial>
      <mass value="5"/>
      <origin rpy="0 0 0" xyz="0 0 0.1"/>
      <inertia ixx="0.0395416666667" ixy="0" ixz="0" iyy="0.106208333333" iyz="0" izz="0.106208333333"/>
    </inertial>
    <!-- body -->
    <collision name="collision_chassis">
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
    </collision>
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <geometry>
        <box size="0.5 0.3 0.07"/>
      </geometry>
      <material name="blue"/>
    </visual>
    <!-- caster front -->
    <collision name="caster_front_collision">
      <origin rpy=" 0 0 0" xyz="0.35 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
      <surface>
        <friction>
          <ode>
            <mu>0</mu>
            <mu2>0</mu2>
            <slip1>1.0</slip1>
            <slip2>1.0</slip2>
          </ode>
        </friction>
      </surface>
    </collision>
    <visual name="caster_front_visual">
      <origin rpy=" 0 0 0" xyz="0.2 0 -0.05"/>
      <geometry>
        <sphere radius="0.05"/>
      </geometry>
    </visual>
  </link>
  
  <link name="link_right_wheel">
    <inertial>
      <mass value="0.2"/>
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <inertia ixx="0.000526666666667" ixy="0" ixz="0" iyy="0.000526666666667" iyz="0" izz="0.001"/>
    </inertial>
    <collision name="link_right_wheel_collision">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </collision>
    <visual name="link_right_wheel_visual">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </visual>
  </link>
  
  <joint name="joint_right_wheel" type="continuous">
    <origin rpy="0 0 0" xyz="-0.05 0.15 0"/>
    <child link="link_right_wheel"/>
    <parent link="link_chassis"/>
    <axis rpy="0 0 0" xyz="0 1 0"/>
    <limit effort="10000" velocity="1000"/>
    <joint_properties damping="1.0" friction="1.0"/>
  </joint>
  
  <link name="link_left_wheel">
    <inertial>
      <mass value="0.2"/>
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <inertia ixx="0.000526666666667" ixy="0" ixz="0" iyy="0.000526666666667" iyz="0" izz="0.001"/>
    </inertial>
    <collision name="link_left_wheel_collision">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </collision>
    <visual name="link_left_wheel_visual">
      <origin rpy="0 1.5707 1.5707" xyz="0 0 0"/>
      <geometry>
        <cylinder length="0.04" radius="0.1"/>
      </geometry>
    </visual>
  </link>
  
  <joint name="joint_left_wheel" type="continuous">
    <origin rpy="0 0 0" xyz="-0.05 -0.15 0"/>
    <child link="link_left_wheel"/>
    <parent link="link_chassis"/>
    <axis rpy="0 0 0" xyz="0 1 0"/>
    <limit effort="10000" velocity="1000"/>
    <joint_properties damping="1.0" friction="1.0"/>
  </joint>
</robot>

What do we have there?

Basically, it’s a robot composed by 3 links and 2 joints. Every robot needs a base link, in this case, the chassis is in charge of connecting all the parts of the robot. See below an image that represents the relation between the links and joints. (Links in green, joints in blue).

STEP 4

We have our robot model defined. Let’s check it in RViz. In order to do that, let’s create a launch file and that opens RViz and fill its robot visualization with our fresh new model.

Create a new folder: ~/simulation_ws/src/m2wr_description/launch/rviz.launch

You can copy & paste the content below to the launch file we have just created:

<?xml version="1.0"?>
<launch>

  <param name="robot_description" command="cat '$(find m2wr_description)/urdf/m2wr.xacro'"/>

  <!-- send fake joint values -->
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher">
    <param name="use_gui" value="False"/>
  </node>

  <!-- Combine joint values -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/>

  <!-- Show in Rviz   -->
  <node name="rviz" pkg="rviz" type="rviz" />

</launch>

Now, open a terminal or get back to the one you had opened before and compile the simulation_ws. (we actually don’t have anything to be compiled, but we need catkin to generate ROS header files, in order to have it into our $ROS_PACKAGE_PATH). After compiling it, launch the RViz visualization of the robot. You’ll execute something like:

user:~$ cd ~/simulation_ws
user:~/simulation_ws/$ catkin_make
user:~/simulation_ws/$ roslaunch m2wr_description rviz.launch

STEP 5

Now, let’s open the Graphical Tools application:

Great! We have a consistent robot model!

Now.. Let’s spawn it into a gazebo simulation. First, create a new launch file: ~/simulation_ws/src/m2wr_description/launch/spawn.launch

Stop the last launch file we started (for RViz), we are going to use the same terminal once again.

Start an empty simulation, from the simulations menu:

You should have the empty simulation ready:

STEP 6

Finally, spawn the robot to the Gazebo simulation. In your terminal, execute the following:

user:~/simulation_ws$ roslaunch m2wr_description spawn.launch

Check gazebo simulation again, the robot is there!

Done!

In case you have missed some part of the tutorial, you can have a copy of the ROSject we generated by writing this post: http://www.rosject.io/l/8e6c887/

In this next tutorial, we will explore the macros for URDF files using XACRO files.

[irp posts=”12948″ name=”Exploring ROS with a 2 Wheeled Robot #2 : XACROs”]

Don’t forget to leave a comment! Let us know what you think about this kind of post! We will be glad to have your opinion!

See you!!

 

Related courses:

What is ROS_MASTER_URI?

What is ROS_MASTER_URI?

Hello ROS Developers! In this post, we will see what the ROS_MASTER_URI is in just 5 minutes. We’ll see what it represents and how we use it in the entire ROS system.

Let’s go!

Step 1: Setup your development environment

To follow this post, you need a computer with ROS already installed. There are three options, but I strongly recommend option 3 as it’s the easiest and the only one I can guarantee will work.

  1. You have ROS installed locally, such that kinetic <= version < crystal. Great, nothing more is needed, just be ready to spin up a terminal.
  2. You don’t have ROS installed but you have installed docker… there’s a way out: run docker run -it osrf/ros:kinetic-desktop in your terminal to pull a ROS docker image. Please note:
    • Docker will “pull” this image if you don’t have it locally already.
    • You need to run this command on every terminal you use in this post, before typing any other command!
  3. Neither ROS nor docker is installed? No problem – launch a ready-to-go development environment on ROS Development Studio (ROSDS) within your browser! If you don’t have an account yet, you can create a free account. Once you log in, create a project and call it rosnode_test. In your project configuration, select Ubuntu 16.04 + ROS Kinetic + Gazebo 7. To “open a terminal”, pick the Shell app from the Tools menu.

Step 2: Run some commands to learn about ROS_MASTER_URI

Open a terminal and run any “roslaunch” command. Let’s use the example shown here (should work where you have a full ROS installation, like in the ROS Development Studio):

user:~$ roslaunch openni_launch openni.launch

...

auto-starting new master
process[master]: started with pid [2846]
ROS_MASTER_URI=http://master:11311

...

The output is a very long one, so I have truncated it, leaving only the part we want to examine. You’ll see that part of the output indicated that a master process was started, and then specified the ROS_MASTER_URI. This is because the two are related.

What then is this “ROS master URI”? Let’s learn about that in the next section.

Step 3: Master the concept – what is ROS_MASTER_URI?

As you might have guessed, ROS_MASTER_URI tells us where we can locate the master ROS process. (We learned about this master process in a different post. Here is the link, in case you have not seen it.) It’s the network address of the computer/device on which the ROS master process is running.

Please take note of the following about ROS_MASTER_URI :

  • it’s a required setting, as ROS is a centralized system; all nodes depend on the master for core service and must, therefore, be able to locate it or they won’t work.
  • the URI must be accessible to nodes on remote computers or devices, so this address needs to be set based on which network we expect these remote computers to be. That’s why ROS wiki warns against using localhost, because this is not normally accessible from a remote PC unless it’s specifically configured to be.

And that’s it! Now you are a master of ROS_MASTER_URI 🙂 .

Extra: Video

Prefer to see the ‘sights and sounds’ version of this post? We made this video just for you!

[youtube https://www.youtube.com/watch?v=xexYf5yuqes&w=560&h=315]

Feedback

Did you like this post? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other. Thank you!

[ROS in 5 mins] 057 – How to publish the position of a robot using TransformBroadcaster in python

[ROS in 5 mins] 057 – How to publish the position of a robot using TransformBroadcaster in python

Hello ROS Developers,

welcome to this new post on the “ROS In 5 Minutes” series!

In this post we are going to see how to publish the position of a robot with Python using the TransformBroadcaster. For that we are going to use Robot Ignite Academy, which is the best platform for those who want to Learn ROS Fast.

Before we start, in case you are new to ROS, remember that we have ROS Basics courses in Python and C++:

Ok, let’s get started. In order to develop our position publisher in ROS we first need to create a ROS package. Our package will be located on the src folder of the ~/catkin_ws (catkin workspace) and its name will be tutorial. Given that we will use python, we add the rospy dependency. For that we use the following commands:

mkdir ~/catkin_ws/src/ -p

cd ~/catkin_ws/src/

catkin_create_pkg tutorial rospy

Now that our package is created, let’s create a python file called broadcaster on its src folder and make it executable with the commands below:

cd ~/catkin_ws/src/tutorial/src/

touch my_broadcaster.py

chmod +x my_broadcaster.py

Now let’s add the code that publishes the positions to our my_broadcaster.py file. The content is as follows:

#! /usr/bin/env python

from tf import TransformBroadcaster
import rospy
from rospy import Time 

def main():
    rospy.init_node('my_broadcaster')
    
    b = TransformBroadcaster()
    
    translation = (0.0, 0.0, 0.0)
    rotation = (0.0, 0.0, 0.0, 1.0)
    rate = rospy.Rate(5)  # 5hz
    
    x, y = 0.0, 0.0
    
    while not rospy.is_shutdown():
        if x >= 2:
            x, y = 0.0, 0.0 
        
        x += 0.1
        y += 0.1
        
        translation = (x, y, 0.0)
        
        
        b.sendTransform(translation, rotation, Time.now(), 'ignite_robot', '/world')
        rate.sleep()
    


if __name__ == '__main__':
    main()

Now that we have everything in place, we just run our code with:

rosrun tutorial my_broadcaster.py

With the code running we don’t see any message. That is the expected behavior since we didn’t call any log functions in our code.

In order to really see the code in action we have to open RViz, which stands for ROS Visualization. For that we need to run in a different shell the following command:

rosrun rviz rviz

Once RViz is running, in order to see it you have to click on the Open Graphical Interface button, the one which is being pointed by a red arrow on the image below:

Once you click that button you will be able to see RViz. The Fixed Frame will be probably pointing to /map, so you have to change it to world as we can see on the next image:

Once we selected the frame we are using as the fixed one we have to add the TF Display. If you look at the previous image you will see on the bottom left a button called “Add“. Let’s click that button and select TF, as in the image below:

After that you should be able to see the positions of our robot being published. The image below shows that.

 

Remember that we also have a video on YouTube that details everything written in this post.

To conclude, I hope you have liked the post and the video. If so, please give us a thumbs up and subscribe to our channel on YouTube: https://www.youtube.com/watch?v=8U-cwv6db3U.

Also, whether you like the video or not, please leave a comment on the comments section of YouTube. Feel free also to share this content with your friends.

Keep pushing your ROS Learning.

 

[ROS in 5 mins] 056 – Five different ways of seeing /tf data

[ROS in 5 mins] 056 – Five different ways of seeing /tf data

Welcome to this “ROS In 5 Minutes” videos series.

In today’s videos we are going see 5 different ways if seeing tf data, which at the end is used to know the positions of robots in a given world, for example.

But before we start, if you want to Learn ROS Fast, remember to take one of the following courses on Robot Ignite Academy:

At the end, whether you like the video or not, please leave a comment on the comments section below giving your opinion.

Thanks for watching.

Pin It on Pinterest