Controlling simulated drones using ROS
ROS, the Robot Operating System, is a collection of frameworks for robot software development created in 2007. The development status is active, so they are actively releasing new versions of ROS. It provides tools and client library implementations in C++, Python, and Lisp. It is one of the biggest open source projects for robotics.
Today, we are going to control simulated drones, using ROS. A drone, also known as UAV, Unmanned Aerial Vehicle, is an aircraft without a human pilot aboard. The one we are going to operate is going to be a quadcopter, a multirotor helicopter propelled by four rotors.
For this tutorial also, we are going to replace the default SITL Copter simulator with one supplied by Gazebo and control the autopilot using the ROS (instead of Mavproxy or some other Ground Control System.
Installing ROS Jade
In this tutorial, we’re using Ubuntu 14.04 since ROS Jade only supports Trusty (14.04), Utopic (14.10) and Vivid (15.04).
Setup your sources.list and keys
Make sure Ubuntu restricted
, universe
and multiverse
repositories are allowed.
1 | sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' |
Installation
desktop-full
package provides us ROS, rqt, rviz, robot-generic libraries, 2D/3D simulators, navigation and 2D/3D perception.
1 | sudo apt-get update |
Initialize rosdep
rosdep
enables you to easily install system dependencies.
1 | sudo rosdep init |
Installing Gazebo
The major version of Gazebo present in ROS is selected at the beginning of the ROS release cycle and will be kept (due to binary compatibility reasons) during the whole life of the ROS distribution. ROS Jade is compatible with gazebo-5.x series. More information about this.
Setup your sources.list and keys
Make sure Ubuntu restricted
, universe
and multiverse
repositories are allowed.
1 | sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-latest.list' |
Installation
1 | sudo apt-get update |
Check your installation
The first time Gazebo is executed it will download some models and it could take some time until it finishes, the screen will remain black, please be patient.
1 | gazebo |
Configure ROS and Gazebo integration
Configuring ROS environment and workspace
It’s convenient if the ROS environment variables are automatically added to your bash session every time a new shell is launched:
1 | echo "source /opt/ros/jade/setup.bash" >> ~/.bashrc |
Let’s create a catkin workspace:
1 | mkdir -p ~/catkin_ws/src |
Even though the workspace is empty, you can still build the workspace:
1 | cd ~/catkin_ws |
Set ROS workspace variables automatically to your bash session:
1 | echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc |
Running ROS and Gazebo
The first time Gazebo is executed with ROS it may take some time, the screen will remain black, please be patient.
1 | roscore & |
The rostopic list
command will give us a list of ROS topics, make sure Gazebo topics are on this list.
1 | rostopic list |
The rosservice list
command will give us a list of ROS services, make sure Gazebo services are on this list.
1 | rosservice list |
Installing MAVROS and Ardupilot’s SITL
Install required packages
1 | sudo apt-get install python-matplotlib python-serial python-wxgtk2.8 python-lxml python-scipy python-opencv ccache gawk git python-pip python-pexpect |
Installation
In this tutorial, we’ll use an Ardupilot’s fork that already contains SITL mode for ROS/Gazebo.
1 | git clone https://github.com/alexbuyval/ardupilot -b RangeFinderSITL2 ~/ardupilot |
These are some other dependencies that we’ll install inside catkin workspace, some are forks that already contain modes for ROS/Gazebo.
1 | cd ~/catkin_ws/src/ |
After downloading all required packages, build using ROS infrastructure catkin_make
.
1 | cd .. |
Running
Start the simulation
Enter the ArduCopter directory and start the SITL simulation.
1 | cd ~/ardupilot/ArduCopter |
The first time you run this command Gazebo screen will be black for some time (it may take some minutes) until it loads the models. Be patient. You might need to reload Gazebo again.
If everything works properly you will see a Gazebo window similar to the one the below.
The rostopic list
command will give us a list of ROS topics, make sure Gazebo, Mavros, and QuadX450 topics are on this list.
1 | rostopic list |
The rosservice list
command will give us a list of ROS services, make sure Gazebo, Mavros, and QuadX450 services are on this list.
1 | rosservice list |
Controlling the simulation through ROS
Now we’ll control the simulation through a script that communicates with mavros node and controls the drone in the simulation.
First, make sure the drone in the simulation is ready to receive messages, the HEARTBEAT
must be connected and the propellers must be moving.
This script is written in Python and teleoperates the drone using a keyboard. First, we’ll set drone mode to Guided Mode, then arm it and do a simple takeoff.
Note: This commands must be used only after the drone is ready to receive them, if you’re receiving RC or Compass warnings, the drone won’t fly. Make sure all the commands were successful by looking at the simulation terminal.
1 | cd ~/catkin_ws/src/mavros/mavros_extras/scripts/ |
If everything works as expected, the drone will fly away (:
You can take a look at ROS Nodes graph by running rqt
utility with Nodes Graph plugin.
Menu Bar -> Plugins -> Introspection -> Node Graph. The node graph must look like the one below.
Script code explained
The script we used to teleoperate the drone is written in Python and uses ROS API to send messages through topics and call services. If you’re not familiar with this concepts I highly recommend you to take a look at this ROS tutorials understanding topics and understanding services.
Once you’re familiar with ROS topics and services concepts we’ll start to see this in action in our teleoperation script. The full script can be found on Github.
1 | rospy.init_node("mavteleop") |
One of the first calls you will likely execute in a rospy
program is the call to rospy.init_node()
, which initializes the ROS node for the process. You can only have one node in a rospy process, so you can only call it once.
1 | override_pub = rospy.Publisher(args.mavros_ns + "/rc/override", OverrideRCIn, queue_size=10) |
rospy.Publisher()
declares that your node is publishing to the /mavros/rc/override
topic using the message type OverrideRCIn
. The queue_size
limits the amount of queued messages if any subscriber is not receiving them fast enough.
1 | rc = OverrideRCIn() |
OverrideRCIn()
will create a message of type OverrideRCIn
and we’ll fill it with information.
1 | override_pub.publish(rc) |
override_pub.publish(rc)
actually publishes to /mavros/rc/override
topic using a newly created rc message.
1 | elif key == 'G': |
Here we’re using the key filter and set drone mode among GUIDED
, ALT_HOLD
and LOITER
.
1 | def set_mode(args, mode): |
Once the mode is selected, it’s time to set using a service. With rospy.ServiceProxy()
we’ll get a container for the request and response type, in this case, service name is /mavros/set_mode
and response type is SetMode
. rospy.ServiceProxy
instances are callable, which means that you can invoke them just as you would with methods, we call it and check its return.
Ready!
This concludes our tutorial on how to control simulated drones using ROS. If you are interested in this topic you can search for popular ROS repositories on Github. There are plenty of open source ROS projects.