Autonomous Navigation of a Mobile Robot: RRT Path Planning Algorithm

Kaan Ucar
Analytics Vidhya
Published in
6 min readSep 27, 2020
Image (1), taken from https://imgbin.com/download-png/HJWCJqwy and used solely with personal purposes.

Read this article in Turkish / Bu makaleyi Türkçe olarak okuyun: https://medium.com/@kucar17/bir-mobil-robotun-otonom-%C5%9Fekilde-yol-bulmas%C4%B1-rrt-algoritmas%C4%B1-57a8c51dfab4

Motion Planning in Robotics is a term which means to find a feasible set of configurations which takes a robot from an initial location to the desired one. Basic RRT Path Planning Algorithm accomplishes that by creating a tree of nodes which connects the starting point to the end (target) point.

On every step, the algorithm selects a random point and then connects that point to the closest point which was already calculated and inserted into the tree of nodes/points. Hence an edge/path is created between those two points. Then the path which connects the two points is checked to see if it collides with any of the obstacles. If there is no collision with the obstacles, this node is added to the tree of nodes. If the path collides with any of the obstacles however, it is decided that the movement is not feasible and same calculations are performed again with a newly picked point. These operations are performed iteratively until the target point or tolerance range is reached.

This algorithm is widely used in Robotics since it can be applied to environments which consist of obstacles. Even though it makes the robot reach its target point, the path calculated by the basic RRT Algorithm is often not optimal as it uses randomly picked points. Despite the fact that there are modified algorithms such as RRT* which are used to optimize the path, we are going to be inspecting the basic RRT Algorithm which has few small touches.

Image (2), animation of an RRT Algorithm which has 10000 iterations. Image belongs to Javed Hossain and it is taken from wikipedia.org (https://en.wikipedia.org/wiki/Rapidly-exploring_random_tree).

Here below, we are going to be covering the act of moving our robot to its objective without colliding into any of the obstacles. RRT Algorithm is going to be run multiple times, in order to create different solutions to particular Path Planning Problem.

Let us inspect the environment (C-space) where our robot is going to find its way:

Our starting point is located at (-0.5, -0.5) and desired point is located at (0.5, 0.5) points.

Since our environment is relatively simple, we can expect our algorithm to give a result which is very close to an optimal one.

We can see the coded — in MATLAB — version of our algorithm below. Firstly our code takes an “obstacles.csv” file as its input and then creates an obstacles matrix with that. Then we assign our start (startNode) and target/end (endNode) nodes to two different variables and limit our algorithm with 50 points. Therefore, our algorithm is going to try to transport our robot to its final configuration by calculating 50 different points at maximum. If the robot is not at its target location after 50 different points are calculated, algorithm is going to tell us that it failed.

In the code, there are few things which might catch your attention. One of them is the fact that sample spaces in X and Y axes get narrowed down separately in each step. For example if our robot reaches the point
(-0.15, 0. 20) without any collision, we tell our algorithm that its new sample spaces are (-0.15, 0.50] and (0.20, 0.50] in X and Y axes, respectively. That way, our algorithm is going to be using those intervals while picking new random points. Even though this approach has the potential of causing problems on certain environments, it helps to create a path which is very close to the optimal one in our instance. Another thing is the fact that straight lines are used in order to connect two points to each other. In systems which have motion constraints, different motion planners are used instead of straight lines. In order to ease the understanding, we are going to be assuming that our robot has no motion constraints.

%% Clearing the command window and workspace
clc
clear
tic%% Defining obstacles
obstacles = readmatrix('obstacles.csv');
centerX = obstacles(:,1);
centerY = obstacles(:,2);
radius = obstacles(:,3)/2;
obstacleCenterX = zeros(1, length(obstacles));
obstacleCenterY = zeros(1, length(obstacles));
obstacleRadius = zeros(1, length(obstacles));
for i = 1 : length(obstacles)
obstacleCenterX(i) = centerX(i);
obstacleCenterY(i) = centerY(i);
obstacleRadius(i) = radius(i);
end
%% Setting up the RRT Aims and Parameters:
startNode = [-0.5 -0.5];
endNode = [0.5 0.5];
maxTreeSize = 50;
T{1} = startNode;
rangeX = startNode(1) : 0.01 : endNode(1);
rangeY = startNode(2) : 0.01 : endNode(2);
nodeNumber = 1;
edge = [];
%% Starting the RRT Algorithm:
while length(T) < maxTreeSize

if(length(rangeX) ~= 0)
xAxis = randsample(rangeX*0.1, 1);
end

if(length(rangeY) ~= 0)
yAxis = randsample(rangeY*0.1, 1);
end

xSamp = [xAxis yAxis];

for i = 1 : length(T)
distances = sqrt((T{1}(1) - xAxis)^2 + (T{1}(2) - yAxis)^2);
index = find(distances == min(distances));
xNearest = T{i};
end

dRange = 0 : 0.005: 0.1;
distanceX = randsample(dRange, 1);
distanceY = randsample(dRange, 1);

xNewAxisX = xNearest(1) + distanceX;
xNewAxisY = xNearest(2) + distanceY;
xNew = [xNewAxisX xNewAxisY];

if (xNew(1) - xNearest(1) == 0)
continue
end

lineCoeffs = polyfit([xNearest(1) xNew(1)], [xNearest(2) xNew(2)], 1);
slope = lineCoeffs(1);
yIntercept = lineCoeffs(2);

% Checking if the line intersects any of the obstacles:
for i = 1 : length(obstacles)
a = linecirc(slope,yIntercept,obstacleCenterX(i),obstacleCenterY(i),obstacleRadius(i));
% If a is not a NaN array (1 by 2), this means collision and loop
% is terminated:
if (~isnan(a))
addCondition = 0;
break
else
addCondition = 1;
end

end

if xNew(1)> 0.5
xNew(1) = 0.5;
end

if xNew(2)> 0.5
xNew(2) = 0.5;
end

% If the line does not intersect the obstacles, xNew is added to the
% tree and vertex/edge is created between xNearest and xNew:
if (addCondition ~= 0)
T{length(T) + 1} = xNew;
nodeDistance = sqrt((xNearest(1) - xNew(1))^2 + (xNearest(2) - xNew(2))^2);
edge{length(edge) + 1} = [nodeNumber nodeNumber+1 nodeDistance];
nodeNumber = nodeNumber + 1;
% Narrowing down the range of sample in order to get closer to the
% goal node:
narrowRangeX = rangeX < xNew(1);
narrowRangeY = rangeY < xNew(2);
rangeX(narrowRangeX) = [];
rangeY(narrowRangeY) = [];

if xNew == endNode
disp('RRT is completed successfully!')
for j = 1 : length(T)
nodes(j, :) = [j T{j}];
end

for j = 1 : length(edge)
edges(j, :) = edge{j};
end

writematrix(edges, 'edges.csv');
writematrix(nodes, 'nodes.csv');
writematrix(nodes(:,1)', 'path.csv')
toc
return
end
end

end
disp('RRT is not completed successfully!')
toc

We expect to get the result “RRT is completed successfully!”, every time we run our code. The reason for that is, we had set the limit of 50 maximum points at the beginning of our code. This limit of 50 points is not a very hard condition for our algorithm. I ran the code approximately 15 times and the maximum number of points the algorithm calculated was 29. However, if we set this limit as 25 or use a different environment, we can expect our algorithm to fail occasionally.

We can see two different paths our algorithm has calculated below (The simulation of the paths were performed in CoppeliaSim simulation software):

The first path which was calculated by the algorithm (26 points).
The second path which was calculated by the algorithm (29 points).

As the two different results show, algorithm may yield different results each time, since it uses randomly picked points.

Collision-free navigation of the robot.

You can find the code and .csv file which consists of obstacles information as well as the other simulation files on my GitHub page.

The simulation environment I used in this article was part of a simulation environment package which was provided by a MOOC series named “Modern Robotics: Mechanics, Planning, and Control Specialization”, which can be found on Coursera. Also this project was inspired by the second week assignment of the fourth course of the same MOOC series.

--

--

Kaan Ucar
Analytics Vidhya

A Control and Automation Engineering student and Artificial Intelligence enthusiast. https://www.linkedin.com/in/kaan-ucar-0b303513a/