User Tools

Site Tools


ros

ROS

ROS Installation

Easy way

  1. Choose a distribution from the one available here
  2. Make sure you got the right Ubuntu release for the ROS distribution you chose, check that here
  3. Follow the install step from the ROS website for the ROS distribution you chose (to install ROS Indigo for example)

Other installations

ROS can be install from source and on other operating systems, a list for ROS Indigo is available here.

ROS Configuration

Once you have install ROS, you need to create a caktin work space and to build it. After that you should setup you terminal to access all ROS features, so add these few lines to your bashrc.

# ROS Config
 
# Source ROS Config files
source /opt/ros/<distro>/setup.bash
 
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make
source devel/setup.bash
 
# Choose editor for rosed command
export EDITOR="subl"
 
# Force ROS package database to update
rospack list > /dev/null
 
# Force rqt plugin database to update
rm -f .config/ros.org/rqt_gui.ini

You must replace <distro> by the name of the ROS distribution you installed previously. The environment variable EDITOR show which editor you want to use when you call the ROS command : rosed. The rospack line force ROS to update is package list and make all new package available to auto completion tab.

How to create a ROS Package

Here is a simple way to create an empty ros package, follow the instructions.

cd ~/catkin_ws/src
catkin_create_pkg NamePackage Dependency1 Dependency2
cd ..
catkin_make
source ../.bashrc

If you choose to create a package where you will use c++, don't forget to add roscpp as dependency. It will create a more custom CMakeList and it will be easier (The same things is true for Python with rospy).

How to install a ROS Package

To install new package use apt-get, for example for web_video_server package type this in a terminal :

sudo apt-get install ros-indigo-web-video-server

Once apt-get finished, don't forget to source bashrc.

source ~/.bashrc

Some ROS Package

You can have the whole list here

Useful commands

  • rospack : info on ROS packages
  • roscd : go into a ROS package directory
  • rosls : list a ROS package directory content
  • rosed : edit a ROS package file

Launching ROS

  • roscore : start ROS Master, ROS Parameter Server, log node
  • rosrun : start a ROS node
  • roslaunch : start multiple nodes

Getting information

See also the ROS Cheat Sheet.

Launch files

The launch files are use to start multiple nodes at once. They use an XML format.

Description of the robot

ROS and GAZEBO don't use same files to describe robots. GAZEBO is a stand alone and use SDF files whereas ROS use URDF files. They are both XML file.

GAZEBO Simulator

ROS and GAZEBO can work together only if you pick the right version for each of them, see this for more information. For example, ROS Indigo work only with GAZEBO V2.

GAZEBO is a stand alone now, but it can still communicate with ROS thanks to gazebo_ros_pkgs. Install it.

sudo apt-get install ros-indigo-gazebo-ros-pkgs

In order for GAZEBO to work, you need to add some lines to your bashrc.

# Gazebo Config
source /usr/share/gazebo/setup.sh 
source /usr/share/gazebo-2.2/setup.sh

You can now launch gazebo with ROS. Start ROS Master in a terminal.

roscore

In an other terminal, start gazebo with gazebo_ros.

rosrun gazebo_ros gazebo

You can now use GAZEBO with ROS. For more information about the gazebo_ros_pkgs install check that link.

URDF Integration in GAZEBO

Setup the file hierarchy

We are going to implement a simple robot in URDF and then spawn it into GAZEBO. Let's call it MYROBOT.

First let's create all the packages.

cd ~/catkin_ws/src
catkin_create_pkg MYROBOT_description
catkin_create_pkg MYROBOT_gazebo
source ~/.bashrc

The file hierarchy for our packages should be like this. Catkin_create_pkg only create package.xml and CMakeLists.txt, you have too create the rest by your own.

../catkin_ws/src
    /MYROBOT_description
        package.xml
        CMakeLists.txt
        /urdf
            MYROBOT.urdf
        /meshes
            mesh1.dae
            mesh2.dae
            ...
        /materials
        /cad
    /MYROBOT_gazebo
        package.xml
        CMakeLists.txt
        /launch
            MYROBOT.launch
        /worlds
            MYROBOT.world
        /models
            world_object1.dae
            world_object2.stl
            world_object3.urdf
        /materials
        /plugins

More information there.

Create the URDF file

Create the file according with URDF Specifications. Once you have created the file, you can check it with this command.

check_urdf MYROBOT.urdf

You can also print it as a graph to have a better view of your model.

urdf_to_graphiz MYROBOT.urdf

For more information see URDF Package Documentation.

In order to be GAZEBO compatible, you URDF file must set <inertia> element within each <link> element.

Create the Launch file

Create MYROBOT.launch and paste this.

<launch>
  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find MYROBOT_gazebo)/worlds/MYROBOT.world"/>
    <!-- more default parameters can be changed here -->
  </include>
</launch>

For a deep understanding of this launch file you can check /opt/ros/indigo/share/gazebo_ros/launch/empty_world.launch in your computer (It's the default path if you didn't touch anything) and read .launch Specifications.

Create the World file

Eventually, create MYROBOT.world and paste this.

<?xml version="1.0" ?>
<sdf version="1.4">
  <world name="default">
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://gas_station</uri>
      <name>gas_station</name>
      <pose>-2.0 7.0 0 0 0 0</pose>
    </include>
  </world>
</sdf>

Check the SDF Specifications for further explanations.

Launching our world

We can now launch the world.

roslaunch MYROBOT_gazebo MYROBOT.launch

Spawning MYROBOT in GAZEBO

Add this line to MYROBOT.launch.

<!-- Spawn a robot into Gazebo -->
  <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-file `rospack find MYROBOT_description`/urdf/MYROBOT.urdf -urdf -model 'MYROBOT'" />

Relaunch MYROBOT.launch. MYROBOT should be in GAZEBO.

Improve URDF file using XACRO

Xacro (XML Macros) is an XML macro language, it allows you to use variables, math operations and other features.

First, make sure that you have Xacro package install on your computer.

sudo apt-get install ros-indigo-xacro

Then you need to make a modification in your MYROBOT.urdf.

<robot name="MYROBOT">
   <!-- #### Random Robot Code -->
</robot>

Become.

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="MYROBOT">
   <!-- #### Random Robot Code -->
</robot>

Finally, change the file extension by .xacro, it's just to remind you, that it's not an URDF file anymore. You can from now on add variables and stuffs.

In order to use xacro file, we need to translate it in urdf again. One way to do that is by adding this lines at the top of your MYROBOT.launch.

<!-- ##### loading parameters ##### -->
<!-- This line convert the xacro file into urdf and stock it in ROS Parameter Server under the name /MYROBOT/robot_description -->
 <param name="/MYROBOT/robot_description" command="$(find xacro)/xacro.py '$(find MYROBOT_description)/urdf/MYROBOT.xacro'" />

And change the line that spawn MYROBOT in GAZEBO simulator.

<!-- Spawn a robot into Gazebo -->
<!-- We just change the argument file by param, to indicate that the URDF description file is in the ROS parameters server -->
 <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-param /MYROBOT/robot_description -urdf -model 'MYROBOT'" />

You can relaunch your launch file now.

Recapitulation

The robot description go on further transformations.

Xacro → Urdf Urdf → Sdf
Command Used xacro.py gzsdf
When Loading robot description in ROS parameters server Spawning robot in GAZEBO simulator

You can use gzsdf command to see the sdf file generated by GAZEBO when you spawn MYROBOT, useful for debugging.

<gazebo> One more thing </gazebo>

You can add the gazebo tag to specify gazebo properties in your URDF/XACRO file. The common way to do it, is to create a MYROBOT.gazebo in MYROBOT_description/urdf. You should put all the gazebo tag in this file and then include it in your MYROBOT.xacro using this line.

<!-- Include -->
  <xacro:include filename="$(find MYROBOT_description)/urdf/MYROBOT.gazebo" />

Here is a tutorial using <gazebo> </gazebo>.

Thus the file hierarchy look like this now.

../catkin_ws/src
    /MYROBOT_description
        package.xml
        CMakeLists.txt
        /urdf
            MYROBOT.xacro
            MYROBOT.gazebo
    /MYROBOT_gazebo
        package.xml
        CMakeLists.txt
        /launch
            MYROBOT.launch
        /worlds
            MYROBOT.world

GAZEBO plugins in ROS

With the GAZEBO plugins, you can access sensors data and motor control using ROS messages and services. The plugins are added using the <gazebo> tag. You can find how adding plugins and a list of all plugins available in gazebo_plugins package here.

For more information you can go to the QuimWiki GAZEBO plugin overview page.

ROS_Control

Overview

According to its creator, ROS_Control allows you to lower the ROS entry barrier to the driver level. It allow you to focus only on drivers and high level application. ROS_Control is made up by two elements, controllers and a robot hardware abstraction. They are linked by hardware interface. There is a picture.

This image is from the following presentation.

Setup your URDF file

You need to add in MYROBOT.xacro some transmission elements. One for each hardware interfaces you will use. Check the Transmission xml specifications.

<transmission name="MYTRANS">
	<type>transmission_interface/SimpleTransmission</type>
	<joint name="MYJOINT">
		<hardwareInterface>VelocityJointInterface</hardwareInterface>
	</joint>
	<actuator name="MYACT">
		<mechanicalReduction>1</mechanicalReduction>
	</actuator>
</transmission>

MYJOINT refer to one of your robot joints already define. They must have the same name. See the Joint Specifications if you have forgot. The full transmission type list is available here and the full hardwareInterface list there and over there.

Create the Robot Hardware Abstraction

First make sure you have install ros control.

Then you need to create a new package with the roscpp and the controller_manager dependencies.

catkin_create_pkg MYPACKAGE roscpp controller_manager

Then paste the following code in src/MY_SUPER_CPP.cpp

#include <hardware_interface/joint_command_interface.h>
#include <hardware_interface/joint_state_interface.h>
#include <hardware_interface/robot_hw.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <controller_manager/controller_manager.h>
#include <string>
#include <transmission_interface/simple_transmission.h>
#include <transmission_interface/transmission_interface.h>
 
#include "ros/ros.h"
 
 
using namespace transmission_interface;
 
class MyRobot : public hardware_interface::RobotHW
{
public:
  MyRobot()
  {
    //HardWare Interfaces
    //connect and register the joint state interface
    hardware_interface::JointStateHandle state_handle_a("MYJOINT", &j_pos[0], &j_vel[0], &j_eff[0]);
    jnt_state_interface.registerHandle(state_handle_a);
 
    registerInterface(&jnt_state_interface);
 
    //connect and register the joint position interface
    hardware_interface::JointHandle vel_handle_a(jnt_state_interface.getHandle("MYJOINT"), &j_cmd_vel[0]);
    jnt_vel_interface.registerHandle(vel_handle_a);
 
    registerInterface(&jnt_vel_interface);
  }
 
  void write(){
  }
 
  void read(){
  }
 
private:
  //Hardware Interfaces
  hardware_interface::JointStateInterface jnt_state_interface;
  hardware_interface::VelocityJointInterface jnt_vel_interface;
 
  double j_pos[1];
  double j_vel[1];
  double j_eff[1];
 
  double j_cmd_pos[1];
  double j_cmd_vel[1];
  double j_cmd_eff[1];
};
 
 
main(int argc, char **argv)
{
  ros::init(argc, argv, "MYPACKAGE_NODE");
 
  ros::AsyncSpinner spinner(1);
  spinner.start();
 
  MyRobot robot;
 
  ros::NodeHandle n;
  controller_manager::ControllerManager cm(&robot);
 
  ros::Duration period(2);
 
  while(ros::ok()){
 
    ROS_INFO("loop");
    robot.read();
    cm.update(ros::Time::now(),period);
    robot.write();
 
    usleep(500000);
    //period.sleep();
  }
}

There are several things to care in this file. First in the MYROBOT Constructor, you can notice the “MYJOINT”, it's there that we point out witch joint is connected to witch hardware interfaces. Furthermore, always in the MYROBOT Constructor, you have jnt_state_interface and jnt_vel_interface. The first one is there to give to controllers the states of MYJOINT. The Second one is there to get back the velocity command send by the controller. One should note that the joint name and the hardware interface type should be the same as describe in your transmission element in MYROBOT.xacro. For more informations.

Choose a controller

You can find and leverage a lot of controllers write by the ROS Community in the ros_controller package. In order for the controller to be compatible with MYROBOT.xacro and our Robot Hardware Abstraction file you should make sure that the hardware interfaces that the controller use are define in both files.

To understand the next example we will assume that you have create a package name MYROBOT_control with two sub-directories config and launch.

Summary

In your URDF file, take care : MYJOINT and MYINTERFACE.

<transmission name="MYTRANS">
	<type>transmission_interface/SimpleTransmission</type>
	<joint name="MYJOINT">
		<hardwareInterface>MYINTERFACE</hardwareInterface>
	</joint>
	<actuator name="MYACT">
		<mechanicalReduction>1</mechanicalReduction>
	</actuator>
</transmission>

In your Robot Hardware Abstraction, take care : MYJOINT and MYINTERFACE.

//HardWare Interfaces
//connect and register the joint state interface
hardware_interface::JointStateHandle state_handle_a("MYJOINT", &j_pos[0], &j_vel[0], &j_eff[0]);
jnt_state_interface.registerHandle(state_handle_a);
 
registerInterface(&jnt_state_interface);
 
//connect and register the joint position interface
hardware_interface::JointHandle my_handle_a(jnt_state_interface.getHandle("MYJOINT"), &j_cmd[0]);
my_interface.registerHandle(my_handle_a);
//Hardware Interfaces
hardware_interface::JointStateInterface jnt_state_interface;
hardware_interface::MYINTERFACE my_interface;

In your config file in MYROBOT_control/config/MYROBOT_config.yaml, take care : MYJOINT. For MYINTERFACE, we should choose a VelocityJointInterface, because diff_drive_controller/DiffDriveController need two VelocityJointInterface.

MYROBOT:
    mobile_base_controller:
        type: "diff_drive_controller/DiffDriveController"
        left_wheel: 'MYJOINT'
        right_wheel: 'MYOTHERJOINT'
        pose_covariance_diagonal: [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0]
        twist_covariance_diagonal: [0.001, 0.001, 1000000.0, 1000000.0, 1000000.0, 1000.0]

In your launch file in MYROBOT_control/launch/MYROBOT_control.launch.

  <!-- Load joint controller configurations from YAML file to parameter server -->
<rosparam file="$(find MYROBOT_control)/config/MYROBOT_config.yaml" command="load"/>
 
  <!--  load the HardwareInterface-->
<node name="hwInterface" pkg="test_hardware_interface" type="test_hardware_interface" ns="/MYROBOT"/>
 
  <!-- load the controllers -->
<node name="controller_spawner" pkg="controller_manager" type="spawner" ns="/MYROBOT" args="mobile_base_controller"/>

Gazebo with ros_control

You can use ros_control with GAZEBO, there is a tutorial here. In this case, you don't need anymore your Robot Hardware Abstraction. GAZEBO come with his own Robot Hardware Abstraction. Add this to MYROBOT.gazebo.

<gazebo>
  <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    <robotNamespace>/MYROBOT</robotNamespace>
  </plugin>
</gazebo>

Ros_control debug tool

You can install a rqt plugin named rqt_controller_manager.

sudo apt-get install ros-indigo-rqt-controller-manager

Don't forget to add this line to your .bashrc.

# Force rqt plugin database to update
rm -f .config/ros.org/rqt_gui.ini

References

ros.txt · Last modified: 2020/03/06 09:25 by tvandenbussche