You are on page 1of 4

1

Controlling Two Quadcopters using ROS


Navigation Stack: A Tutorial

Resumo—The Navigation Stack implemented in ROS is well the Navigation Stack, converting into rotors commands
know package used to control terrestrial robots, known as in a making the quadcopters to be moved.
2D map. The unmanned aerial vehicle (UAV), popularly known The communication to and from the ROS’s Navigation
as drone, flies in three dimensions. One can use ROS’s Navigation
Stack is made of topics and “transformation” ROS objects.
Stack package by considering the quadcopters flying in a single
altitude. So, the present work proposes to demonstrate how to Each transformation is identified by frame_id. The figure 1
use the ROS’s Navigation Stack to control two quadcopters. Also, can be seen this structure. The “transformation” is a mecha-
here explain how to configure Navigation Stack and the result of nism where the roscore execute translation and rotation process
the experiments, as well the difficulties encountered during this and they are published by a special topic called /tf.
work. This work is not focus covering create a new kind of the
path finder algorithms, but it uses an already implemented in
the ROS package.
Index Terms—Robotic Algorithm ROS swarm

I. INTRODUCTION
It is considered that the reader has basic knowledge of ROS
and CollpeliaSim. Below a brief description and respective site
address are cited. Please check them out.
The ROS [1] is a set of software libraries and tools that help
you build robot applications. One the most versatile package is
Figura 1. The structure of ROS’s Navigation Stack. Source:
the Navigation Stack. The CoppeliaSim [2] is a robot simulator http://wiki.ros.org/navigation/Tutorials/RobotSetup
integrated with ROS, BlueZero, among others.
The state of the art on the use of the Navigation Stack The first configuration to accomplish this work was creating
package, in addition to the ROS Tutorial, some publications a scenario with two quadcopters. Next, the YAML [7] and
can be cited as a good way to help understand the configuration the XML launch files used by ROS’s Navigation Stack is
and possible use of the Navigation Stack in a real robot. Zheng configured to control both quadcopters, as well the json files
[3] explain how to tuning Navitagion Stack parameter like with some coordination to be sent to each quadcopter.
maximum and minimum values to setup velocity, acceleration, And finally created the algorithm witch will start the Coppe-
inflation zone, the global path planing algorithms and so on. liaSim and ROS’s Navigation Stack and send the coordenates
Another good guide about the Navigation Stack is described as goal sequential. This algorithm was written in Python 2.7
by Rodrigo et al. [4]. In this article they describe detailed compatible.
step-by-step how configure and use it in a real robot. A work
related about UAV can be found in Ayanian [5] showing how
to use it in a real UAVs. Another good tutorial using UAV and A. Quadcopter Configuration in CoppeliaSim
ROS’s Navigation Stack is Fairchild [6]. The ROS’s Navigation Stack also has a lot of commonly
The rest of this work is organized as (i) Configuration of used sensors, for instance, a LIDAR. Each quadcopter has a
ROS Navigation, (ii) Experiments (iii) Results Difficulties, and LIDAR sensor above its frame.
finally (iv) Conclusion.

II. CONFIGURATION
The following session describe the configuration amount the
components in this work.
The idea of the structure is shown as:
• First, some coordinates in written in a Java Script Object
Notation (JSON) format file.
• After started, our algorithm will send each coordinate as
a goal to the ROS’s Navigation Stack which will create a
path, avoiding obstacles, sending the linear and angular
velocity commands via ROS topic to quadcopters again
and again, up to quadcopter reach the goal. Figura 2. The Light Detecton and Ranging - LIDAR.
• Once the quadcopter reaches the goal, the our algorithm
sends the next coordinate and so on, until the all coordi- The specifically changes made in the Lua script is about
nates written in JSON file has been sent. communication to and from roscore by ROS topict. Below is
• The Lua script of each quadcopter will receive those explained the changes.
velocity commands, one by one from ROS topic sent by In the quadcopter script:
2

• The odometry data are publish by <launch>


pubOdom=simROS.advertise <!-- ROS’s Navigation Stack configuration for the
(’/odom0’, ’nav_msgs/Odometry’) as a ROS’s topic. first Quadcopter. -->
• The rotors commands is receibed by <group>
sub=simROS.subscribe
<node pkg="move_base"type="move_base"respawn=
(’/cmd_vel0’, ’geometry_msgs/Twist’,
"false"name="move_base0"output="screen
’cmd_vel_callback’) as a ROS’s topic.
• The function getTransformStamped(objHandle,
<rosparam file="$(find quad)/yaml_quad/
name,relTo,relToName) costmap_common_params0.yaml"command=
just generate and return a
structure of ROS’s "load"ns="global_costmap"/>
geometry_msgs/TransformStamped to be published <rosparam file="$(find quad)/yaml_quad/
as a Transformation (TF). This function is use in lines: costmap_common_params0.yaml"command=
tf_pose=getTransformStamped(RobotHandle, "load"ns="local_costmap"/>
’base_link0’,OdomHandle,’odom0’) <rosparam file="$(find quad)/yaml_quad/
that is just used to make up the odom variable and be local_costmap_params0.yaml"command=
sent as a topic later with their respective frame ids. and
"load"/>
transforms=
getTransformStamped <rosparam file="$(find quad)/yaml_quad/
(RobotHandle,’base_link0’,OdomHandle, global_costmap_params0.yaml"command=
’odom0’), "load"/>
getTransformStamped <rosparam file="$(find quad)/yaml_quad/
(OdomHandle,’odom0’,MapHandle,’map’), base_local_planner_params0.yaml"command=
getTransformStamped "load"/>
(SensorHandle,’Lidar0’,RobotHandle, <param name="conservative_reset_dist"type=
’base_link0’),
"double"value="1.0"/>
<param name="controller_frequency"type=
The transforms variable is an array with three
transformation structure. "double"value="1.0"/>
• The simROS.sendTransforms(transforms) code tells
to the roscore to execute transformation using the <remap from="/clicked_point"to="/clicked_point0"/>
transforms array. <remap from="/cmd_vel"to="/cmd_vel0"/>
In the LIDAR script: <remap from="/initialpose"to="/initialpose0"/>
• The code pub=simROS.advertise(’/scan0’, <remap from="/odom"to="/odom0"/>
’sensor_msgs/LaserScan’) register in roscore as a topic <remap from="/scan"to="/scan0"/>
publisher. <remap from="/move_base_simple/goal"
• This code prepare and publish the LIDAR data d={} to="/move_base_simple/goal0"/>
d[’header’]={stamp=simROS.getTime(), <remap from="/move_base/goal"
frame_id="Lidar0"}
to="/move_base/goal0"/>v </node>
d[’angle_min’]= -scanRange*0.5
</group>
d[’angle_max’]= scanRange*0.5-stepSize
d[’range_min’]= 0.02
d[’range_max’]= 60 <!-- ROS’s Navigation Stack configuration for the
d[’angle_increment’]=stepSize second Quadcopter. -->
d[’ranges’]=distsROS .... Same as <group> above, just changing the index
simROS.publish(pub,d) number, like "move_base1"
The trick to allow two, or more, robot with the same code <!-- Configuration for the ROS RVIZ. -->
just enumerate the CopperliaSim internal names e.g. Quadcop- <group>
ter0, Quadcopter1, Lidar0, Lidar1 and so on. As well as, for <node type="rviz"name="rviz_quad_multi"pkg=
sending similar ROS’s topic getting no conflict just enumerate "rviz"args=-d $(find quad)/rviz/quad_multi.rviz
the topic and the fram ids names. For instance, base link0 </node>
and base link1, odom0, odom1, /cmd vel0, /cmd vel1 and so
</group>
on.
</launch>

B. ROS’s Navigation Stack Configuration


The XML lauch file references two set of YAML files, one
The Navigation Stack must be started twice to control for each quadcopter. In this files are configure core of ROS’s
both, one for each quadcopter. The ROS’s Navigation Stack Navigation Stack to control a robot. Each set is compose by:
is configured thru YAML files and XML ROS launch files.
So two set of YAML files was used and on launch files with • costmap common params.yaml: The costmap parame-
setting up both configuration as follow in this session. ters is used to setup the cost to create a path in the map.
The XML launch file configured for this work is divides in The parameter in there are strongly tied with the structure
three groups, configuration for (i) the fist quadcopeter0, (ii) of the robot.
the second one quadcopter1 and (iii) a group to start rviz that • global costmap params.yaml: The global cost para-
let monitor the quadcopters move. meter allow the ROS’s Navigation Stack control the
3

transformations (via ROS /tf) related to the global map height: 12.0
and robot frame base.
• local costmap params0.yaml: On the Simultaneous lo- • local costmap params0.yaml
calization and mapping (SLAM), the local map is more local_costmap:
detailed them global map, but the robot localization in global_frame: map
the local map must be synchronized with global map. robot_base_frame: base_link0
• base local planner params1.yaml: The tuning parame-
update_frequency: 4.0
ter related to the commands sent by ROS’s Navigation publish_frequency: 2.0
Stack is set in this file. static_map: false
The two set of files described above was been create as rolling_window: true
show in table I. width: 3.0
height: 3.0
Tabela I
resolution: 0.025
YAML FILE SET FOR EACH QUADCOPTER .
origin_x: 0.0
origin_y: 0.0
Quadcopter0 Quadcopter1
base local planner params0.yaml base local planner params1.yaml
Both set of files have same parameters values despite of
costmap common params0.yaml costmap common params1.yaml
the frame ids and topic names. There are certainly other
global costmap params0.yaml global costmap params1.yaml configuration parameters. However, these are the necessary for
local costmap params0.yaml local costmap params1.yaml the proposed work.

The files of one set are listed below. The only difference C. The Control Algorithm
is the suffix “0” for first quadcopter and “1” for second one.
Please, notice the values of the frames id and the topic values. The ROS’s Navigation Stack wait for a topic of
type “geometry msgs/PoseStamped” with the default name
• base local planner params0.yaml “/move base simple/goal” as the goal to reached by the
TrajectoryPlannerROS: quadcopter. It represent a position and orientation of the
max_vel_x: 0.3 robot at end of movement. With this information, the ROS’s
min_vel_x: 0.1 Navitagion Stack calculate the best path taking into account
max_vel_theta: 0.7 the obstacles observed by the sensor, the LIDAR in our case.
min_in_place_vel_theta: 1.0 The LIDAR data are from topic “/scan”. The ROS’s core
acc_lim_theta: 3.2 commands the quadcopter movement sending each point of
acc_lim_x: 2.0 the path by publishing topic of type “geometry msgs/Twist”
acc_lim_y: 2.0 with default name “/cmd vel”. Also, it keeps tracking the
holonomic_robot: false quadcopter possition thru the topic default named “/odom” and
meter_scoring: true processing the LIDAR data looking for new obstacle,where in
case it update the path avoiding collision with some possible
• costmap common params0.yaml new obstacles.
The way to change de default name of all need topic name
obstacle_range: 2.5
is done using the tag “remap” in the XML lauch file, as
raytrace_range: 3.0
reproduced below.
inflation_radius: 0.40 robot_radius: 0.35
<remap from="/clicked_point"to="/clicked_point0"/>
transform_tolerance: 0.8
<remap from="/cmd_vel"to="/cmd_vel0"/>
observation_sources: base_scan
<remap from="/initialpose"to="/initialpose0"/>
base_scan: sensor_frame: Lidar0,
<remap from="/odom"to="/odom0"/>
data_type: LaserScan,
<remap from="/scan"to="/scan0"/>
topic: scan0,
<remap from="/move_base_simple/goal"
expected_update_rate: 21.0,
to="/move_base_simple/goal0"/>
observation_persistence: 1.0,
<remap from="/move_base/goal"to="/move_base/goal0"/>v
marking: true,
<remap from="/clicked_point"to="/clicked_point1"/>
clearing: true,
<remap from="/cmd_vel"to="/cmd_vel1"/>
min_obstacle_height: -0.10,
<remap from="/initialpose"to="/initialpose1"/>
max_obstacle_height: 2.0,
<remap from="/odom"to="/odom1"/>
obstacle_range: 2.0,
<remap from="/scan"to="/scan1"/>
inf_is_valid: true,
<remap from="/move_base_simple/goal"
raytrace_range: 6.0
to="/move_base_simple/goal1"/>
<remap from="/move_base/goal"to="/move_base/goal1"/>
• global costmap params0.yaml It is important realize those remaps, because the ROS’s
global_costmap: do nothing before receive the “/move base simple/goal0”
global_frame: map and “/move base simple/goal1” and all topic must be work
robot_base_frame: base_link0 together without interfering on each others. Bear it in mind,
update_frequency: 3.0 the algorithm that might be sending a couple of goals to
static_map: false two different topics (i.e. “/move base simple/goal0” and
width: 12.0 “/move base simple/goal1”) must aware of this configuration,
4

also must to know the actual specifically quadcopter position IV. RESULTS AND DIFFICULTIES
to send the next goal but only it has been reached the A. Results
previews one.
The goals list is defined in JSON file format. One for each The issues about linear and angular velocity together with
quadcopter: obstacle inflation. It is worth observing the quadcopter fo-
otprint invades the inflation area. The velocities are defined
• quad0 goals.json
setting the parametes “max vel x: 0.3”, “ min vel x: 0.1”
"goals": [[3.0,6.5],[9.0,5.5],[1.5,9.0]] in the base local planner params#.yaml YAML file. Other
• quad1 goals.json critical moment is when both quadcopters scan each other by
"goals": [[4.0,3.5],[2.0,9.0],[8.5,5.0]] The algo- thear LIDAR sensor. The ROS’s Navigation Stack resolves the
rithm developed in python to do it has the main functions: conflict. The results shows that issues has been reached.
• Start the CoppeliaSim simulation. The user must
open scene “rosQuad NAVSTACK 4 arena.ttt” in Cop- B. Difficulties
peliaSim, but it is not need to start simulation As can be realized, the main issue to cope with ROS’s
execution. The algorithm will do it by calling Navigation Stack is to choose the right values to setup the
vrep.simxStartSimulation parameter in the YAML files. The main issues are:
(vrepID,vrep.simx_opmode_blocking), a build in func- • The LIDAR range definition: We must be care to
tion give by Coppelia Robots externa interface. define a good value for “obstacle range” of the LIDAR
• Read the files quad0 goals.json and quad1 goals.json sensor. Due to the inclination of quadcopter need to
JSON format and create arrays and small sphe- start horizontal movement, a large range could detech the
res on the position that will be sent as topic grond as obstacle.
/move base simple/goal0 and /move base simple/goal1, • The linear movement: If the quadcopter is so fast the
respectively. The movement sequences are show in figure pitch angle is bigger making the LIDAR range must be
3. configured smoller. It happens, again to avoid the LIDAR
• Create two threads to control the goals arrays. Each detect the ground as obstacle.
thread keep an eye on the specifically quadcopter position • Angular velocity: If the angular velocity is too low
using the “/odom0” and “/odom1” topics information. compared to a high linear velocity the quadcopter do not
When the quadcopter get close the goal coordinate the turn to left or right in a acceptable time.
algorithm send new respectively goal, “/cmd vel0” and The acceptable values was found making trade-off among
“/cmd vel1”. those parameters and adjusted during the tests.

V. CONCLUSION
This work propose to demonstrate to configuration and
user the ROS’s Navigation Stack. We show the structure,
the configuration files and how they all work together. After
running, the result was shown with results. The conclusion
is that the ROS Naviagion Stack is capable of controlling
more than one robot. However, controlling more than two
quadcopters using V-REP with this control complexity has
become unacceptable in terms of performance. The next job
Figura 3. Seguence of goals to be reached by each quadcopters.
could use ROS Navigation Stack to control two or more real
quadcopters.

R EFER ÊNCIAS
III. EXPERIMENT
[1] Stanford Artificial Intelligence Laboratory et al., Robotic
During the tests several parameter values of goals was used, Operating System, Version: ROS Melodic Morenia, 2018-05-23,
trying to tease collision against obstacle and between each https://www.ros.org.
others, as shown in the figure 3. [2] E. Rohmer, S. P. N. Singh, M. Freese, “ CoppeliaSim (formerly
V-REP): a Versatile and Scalable Robot Simulation Framework”,
The figures 4 shows one critical situation observed during IEEE/RSJ Int. Conf. on Intelligent Robots and Systems, 2013.
the tests. www.coppeliarobotics.com
[3] Kaiyu Zheng, ROS Navigation Tuning Guide. 2016
arXiv:1706.09068v2 [cs.RO]. At 8 Apr 2019 add on
amcl.
[4] Rodrigo Longhi Guimarães, André Schneider de Oliveira, João Fabro,
ThiagoBecker, and Vinı́cius Amilgar Brenner, ROS Navigation: concepts
and tutorial, DOI: 10.1007/978-3-319-26054-9 6, February 2016 Studies
in Computational Intelligence 625:121-160.
[5] Hönig W., Ayanian N. (2017) Flying Multiple UAVs Using
ROS. In: Koubaa A. (eds) Robot Operating System (ROS). Stu-
dies in Computational Intelligence, vol 707. Springer, Cham.
https://doi.org/10.1007/978-3-319-54927-9_3
[6] Fairchild, Carol and Harman, Thomas L, ROS robotics by example,
Packt Publishing Ltd, 2016.
Figura 4. The collition has been resolved by Navitagion Stack. [7] YAML file format, proposed by Clark Evans, 2001,
https://en.wikipedia.org/wiki/YAML.

You might also like