Obstacle Avoidance

Introduction.



The aim of this project is for our car to complete a full lap around the circuit without colliding with any of the obstacles placed along it. We will be using the VFF (Virtual Forces) method. Our only sensors will be an array of lasers located at the front of the car.

Although our code will be (again) reactive-method-based, we will require a map to show us the location of the targets we are to reach. Our global locating system will also be constantly providing us with the location of the robot.

Despite how similar this exercise might seem to the Follow Line project, their implementations are completely different. For this exercise we are provided with an array of lasers instead of a camera, so there will be no filtering and no colour spaces. Our lasers will measure distance in a specific direction and will return a number.


VFF Explained.
As I said, we will be using this method to compute both the forward speed and the turn speed of the robot. This method calculates the movement direction of the robot as the resultant vector of the addition of simulated forces from our environment. There is an atractive force coming from what is called the target, that will entice the robot towards it. There's also a repulsive force coming from the different obstacles the robot is presented with that will make it avoid contact with them. Our robot's movement direction and speed should be calculated according to the addition of both atractive and repulsive forces.



In the picture we can see how the resultant force (green) is calculated as the sum of the other two forces.


Map guidance and coordinates systems.
Our robot must be provided with a map to be able to see the target from out of the laser's range. The map grants us information regarding the absolute location of the target and the robot within it. We get such information by calling the designated method: getNextTarget(), getCarDirection()... Nevertheless, in order to calculate the direction and strength of the pulling vector that will guide us towards the target we need to know how far target and robot are from each other both in the x axis and in the y axis independently. Such distance is the difference between the absolute coordinates of the target and the robot. 
To help us calculate this we were given the absolute2relative() method.

Regarding the targets, not only do circuits have many turns, but the track describes a circular closed shape, thus making it impossible for a single target to guide our car around it. There will be several targets placed along the circuit that our car will be following, one at a time. Every time our car gets within a certain distance of the target, we get the next target to follow from the map.

Laser output and arrangement.
We build our atractive force by using the map, but in order to build the repulsive vector that will avoid the robot from colliding against obstacles we need information from the lasers. The output of a laser is just a number representing how far is the nearest obstacle in that direction, but there isn't much we can do with just a bunch of numbers: we must know how the lasers are displayed in order to build the vectors. 

There are 180 lasers arranged in a semicircle facing forwards, so each laser will be at the same degrees its index in the array is. We can use this information to translate module and angle into their x and y coordinates by multiplying that module by cos(index) and sin(index). We will then calculate the mean vector of all these numbers and use that as our repulsive vector.

Since we don't know how far our lasers can reach or how precise they become from far distances it is advisable to set a threshold over which laser measurements will not be considered for the mean repulsive vector.

Resultant force.
At this point we have calculated both the atractive force and the repulsive force. All there is left is to add them up to get the resultant force which will be guiding our robot. We use parameters, as always, to tune up its performance. We might want the robot to be more rash, thus being faster; or maybe we want to prioritize safety over haste by giving more importance to the repulsive force.

There's a particular case we have to handle properly. Notice that those two vectors we are adding to calculate the resultant force might at certain point nullify each other. It is not a highly likely scenario, but any time our car faces an obstacle which is totally centered the vectors will be opposite and this may happen. In this situation, and in order to avoid the resultant force to be chaotically fickle, I decided that whenever the module of the resultant force is smaller than a certain constant, instead of that value we will use the repulsive vector as our movement vector.

Getting faster.
So far so good. Our car can complete a full lap without colliding with any obstacle or wall. Nonetheless, we can do better. This implementation of the VFF method limits how fast our car goes to the parameter of the atractive force. We cannot make it extremely high lest our car ignore obstacles and go straight to the target, thus colliding. But this remarkably hinders our time performance, so perhaps we can differentiate two cases: whether we are approaching an obstacle or not. If there's no obstacle in front of the car, it can go lightning fast to the target, but it must slow down whenever it reaches a target. This way its lap time is greatly reduced.

You can check this video to see for yourself:




Comments

Popular posts from this blog

Follow Line (Racing Car)

Cat & Mouse Drones