For our MEng group project this year we have decided to use Robot Operating System (ROS). I thought it would be a good idea for me to do a little blog post on the subject to explain what ROS is and why we are using it. For some of my blog readers this post my have too much geekspeak. I have tried to translate that into English throughout where ever possible and I welcome you to try to follow along with it. However, if this is too much effort or you find yourself feeling confused, don't worry about just skipping this post as it probably isn't for you.
What is ROS?
ROS (Robot Operating System) provides libraries and tools to help software developers create robot applications. It provides hardware abstraction, device drivers, libraries, visualizers, message-passing, package management, and more. ROS is licensed under an open source, BSD license.
ROS is free, open source software for controlling and modelling robots. It includes many useful features that allow developers to get on with the more interesting features of programming and controlling robots. It works by distributing tasks over multiple nodes (explained below) allowing quick and easy expansion and layers for the projects.
A ROS node is an executable within a ROS package.
Each ROS node can be thought of as an individual program. They are connected together by talking to a "Master" node which provides a client library for communication. In English this means that the Master node helps the 'programs' (nodes) to talk to each other (simple)!
A node is started by typing:
rosrun [package-name] [node_name]
A list of currently running nodes can be found with
Nodes can publish or subscribe to topics and can also provide or use services (explained below). To find out which topics a node is publishing, subscribed to and which services it provides you can use the command:
rosnode info [node_name]
Topics are the way nodes communicate in ROS. A node can subscribe to a topic or publish on it and there is no limit to the number of nodes that can subscribe to or publish on any given topic. Here I will discuss topics and give commands relevant for topics. To really learn about topics please see the ROS tutorial on topics.
Communication on topics happens by sending ROS messages between nodes.
In order for your nodes to talk to each other they must send ROS messages. For this communication to work both the publishing node and subscribing node need to be using/expecting the same type of data: You can think of this as both nodes speaking in the same language (e.g. both speaking English).
A topic type is defined by the message type published on it.
Again using the speaking analogy this means that the language a conversation is happening in is defined by the language the messages are spoken in - which makes sense really!
A topic's type can be explored by using the command
rostopic type [topic] and the output of the command will be a ROS message type. The ROS message type analogous to the language that is being spoken.
For programmers ROS message types can be thought of as being like structures in C and are just a way to encapsulate arguments. To see what arguments are used in a ROS message type use the following command.
rosmsg show [type] The output will be a list of arguments with their variable types.
A node publishing to a topic can be thought of as the person speaking in the conversation. There are no limits to how many nodes can publish to a topic and multiple nodes can publish at the same time.
Using the terminal you can play around with publishing on topics. Once you have explored the topic type and message type you can use the following command to post a message to the topic:
rostopic pub [topic] [msg_type] [args]
This allows you to explore publishing your own messages.
A node can subscribe to a topic to receive all messages published on that topic. This is like the people who stand listening to the conversation.
Being 'superhuman' the node listens to all of the messages (in the order they were received). A node can listen a LOT faster than you or I.
rostopic hz [topic] can be used to find out the rate at which messages are being published to a topic in hertz. In simple speak, this is how fast the nodes are talking to each other in messages per second.
If you wish to explore the messages being posted to a topic you can use the ROS topic command to subscribe to a topic and print all messages sent to it on the terminal:
rostopic echo [topic]
Services allow nodes to send a request and receive a response.
Services differ from topics by being event driven. A node can provide a service however this service is not used and therefore does not take any resources until it is called.
A topic is an open form of communication allowing for messages to be sent and received at any time. Whilst a node is subscribed to a topic, a thread for that topic exists and is listening for published data. A service on the other hand must be explicitly called and only fires during that event.
A service can have any number of parameters or none at all. This means that some services you can just call by name and they will run, others require you give them information first before they run. A service may or may not give back a response.
Like topics, services have a type. Using the command
rosservice type [service-name] will show the service type used in calls to that service.
rossrv show [type] will show the arguments with their data types for a given service type. Response arguments and their data types are also given after a separator.
Why are we using it?
Our project is to create software to control an autonomous quadrocopter. Using ROS for this means that we are able to break the task up between multiple members of the group each developing their own node.
As this is a very active area of research, using ROS means we are able to use pre-developed nodes for ROS for connecting to the drone and sending commands (Comms node) simplifying the development of our project and allowing us to focus more on the areas of the project that are related to the control and autonomy.
Many of the pre-developed nodes related to the vision control aspects of the task are experimental research. These nodes are of use to us as a start point for our control. However they may require alteration in order to best utilize them in our project.
By generating a list of needed nodes, their functionality and listing the requirements for each, the architecture for the project is defined and the task of project management can be simplified. As each team member will work on their own node, allowing agile methods of project management to be used.
The architecture of our project is as follows. Each node can be worked on by an individual or group and pre-developed libraries will be used where possible.
- Comms node - handles all communication to and from the drone
- Raw image - raw image from drone's camera
- Nav data - nav_data from drone
- control - commands to be sent to the drone
- take off - make the drone take off
- land - make the drone land
- reset - toggle emergency condition
- Control node
- control - messages to control the drone's flight
- path - planned path to fly drone along
- Vision node
- localisation - VSLAM localised info
- point cloud - points from VSLAM
- Raw image - raw image from drone's camera
- Pathplanning node
- path - path to avoid obstacles / reach objective
- point cloud - points from VSLAM
- Visualisation node
- 3D Map
- point cloud
A hot-swap approach to testing can be used for the project thanks to the nature of ROS. For example, multiple different pathplanning nodes may be written by different members of the group. One by one these can then be run as the pathplanning node, without the need to restart the rest of the system, and each can then be evaluated. The best version of this node can then be chosen and used in the final project.
One of our goals was to ensure that future development on top of the work our team does on this project is possible. The modular approach to ROS allows for object-oriented encapsulation principles to be applied. This means that each node is independent of the others allowing for one to be changed without it affecting the overall system. By having this facility, in the future nodes can be added or altered within the project without risking the functionality of the other nodes.
In conclusion, ROS is perfectly suited to our project's requirements and allows us to achieve our goals whilst saving time and allowing for rapid prototyping and iterative testing.