In the series ‘How to make a robot move’ we will discuss in several blog posts how to make robots move. This first introductory blog will focus on the communication towards robots, using motion planning and robot drivers. Other blogs will go more into depth and focus on how to generate motions, how motions can be used in various applications and what problems may occur. We will use Smart Robotics and the way we work as an example for this series of blog posts. In this first communication blog we will largely focus on how and what to communicate to robots to execute motions.
The importance of motion planning
At Smart Robotics, we cater several markets such as E-commerce, Food, Pharma and FMCG. For many of our applications, we use a robot by Universal Robots. It is a cobot, meaning it can work safely together with people. As it has a relatively small payload and reach, we need to ensure we get the most out of the robot. We have gone through multiple iterations in our products to get closer and closer to the requirements of our customers. As an example, one of the most important requirements for our customers is fast cycle times (or Takt times).
To get closer to the requirements of our customers, we decided to work on creating our own motion planning for communication towards the robot. This has two main benefits:
- Total control over the executed motion; allowing for different motion planning solutions.
- Being able to respond reactively to the environment, I.e. change the trajectory of the robot while being in motion.
To understand these benefits, let us look back at a previous implementation and the limitation of this approach.
Previous robot communication implementations
There are several robot manufacturers, each with their own hardware and software implementation of a robot. Most provide a programming environment to program the robot with. Examples of such manufactures are Universal Robot, ABB, KUKA and Staubli.
One of the possibilities is to write your robot program in these scripts directly, creating the benefit of being able to use all the features from the robot manufacturer. However, it makes your program tightly coupled with the robot manufacturer.
A second solution is one we have deployed at Smart Robotics in the past, using two features that most robot manufacturers provide: motion primitives and remote script sending.
- Motion primitives are low-level commands in the script language for moving the robot. The two most common commands are:
- MoveL: Moves the end-effector in cartesian space
- MoveJ: Moves the end-effector in joint space
- Remote script sending; sending scripts to the robot which the robot then executes.
Given these features, you can set up a pipeline that communicates a combination of motion primitives to control the robot, using the controller and reference generator provided by the robot. An application can send motion goals, and these can be sent to the robot using the remote script sending feature.
However, this approach has a few drawbacks:
- The first being reactivity: for example, an UR robot can only cancel current motion goals by stopping the robot and then executing a new motion primitive. This takes time.
- The second being the control over the path: because the controller and the reference generator are essentially a black box, we experienced some strange behaviors with the motion primitives for the UR robot, for which a cause was not discovered.
A new way of robot communication
For the development of a new approach a few goals were set, addressing the above-mentioned drawbacks:
- The robot should react quickly while being in motion – Hence, updating the trajectory in place was in important to reach the fast cycle times required by customers. For example, you may want to move the robot to a known position close to a product while a camera calculates the product position simultaneously. This product position could then be used to already generate a new trajectory for the robot to move towards. This path should be updated in place so that the robot can move to the new position without stopping.
- We want to take control over the path execution and experiment with different motion planning techniques so that the same communication pipeline can be used for various types of robots.
To reach our desired goals, another feature has been used that most robotics suppliers provide; the ability to execute joint commands. In the UR the servoj function is used for that purpose. Instead of using the motion generator of the robot, we have developed our own motion planner as well as a driver that communicates directly with the UR through a joint-streaming socket. The driver can communicate with the UR and other robots using real-time frequencies of 125hz to 250hz.
Robot communication in practice: an example
Look at the following situation: there is a Python file that can send commands to a robot system, in this case the UR, using our own motion executive through our driver.
The driver is built as a library that is ROS-agnostic. The library can be included in a ROS based project so that it can hook into the ROS ecosystem. The driver is based on the open-source project of ASIO, which provides high-speed asynchronous IO communication. Below you can see how this is set up at a high level:
In the image above we have exposed functionality of the robot through several ROS topics (orange), Action Servers (red) and Services (green). In the image you can also see the split between the ROS-specific wrapper and the more general driver library.
The driver uses the script sending functionality to open a streaming socket to which joint references can be communicated. Below you can see a diagram that showcases how the driver sets up a connection.
In addition, we also open a general command port to send non real-time messages to the UR, such as switching the Payload or Tool Center Point (TCP). This port is extendable and allows more commands that target specific features of the robot to be exposed.
Because the UR was not specifically designed with this use-case – the real-time streaming of joints – in mind, several problems had to be solved. For example, because the joints are streamed using a standard socket interface, connection latency can cause the joint references to arrive late. To compensate for this, we buffer the references in an intelligent way so that we improve stability but keep the responsiveness that we require.
In addition, we also needed to solve for specific behaviors inherent to the UR. For example, in case of a robot emergency stop, the script is cancelled, and the sockets are closed. In the case of a protective stop, the script is simply paused. There are several other edge cases that needed to be accounted for. Therefore, our driver is designed in such a way that it monitors these states and has intelligent reconnection strategies, so that it can recover from these edge cases. How we solved these problems, however, will be a topic for a future blog post.
New driver for different types of robots
The driver designed by Smart Robotics enables the streaming of joints at high frequency and enables the updating of a trajectory on the fly. This in conjunction with the motion executive for the path planning solves the main drawbacks of the previous implemented approach and is also very extendable. As we only need a robot hat can follow joint references, we can port the driver to other types of robots, which we have already started to explore. Creating software that is robot-independent is one of our main focuses, and the above described motion planner and driver are important steps towards that goal.