This project is an self-driving car with object avoidance.
Team members: Ian, Sammuel.
This car was designed to participate in the WRO Future Engineers Category. This documentation explains how the car functions as well as the solutions for various problems. Team Information is provided as well.
The self-driving car challenge in this season is a Time Attack race: there will not be multiple cars at the same time on the track. Instead, one car per attempt will try to achieve the best time by driving several laps fully autonomously.
The traffic signs indicate the side of the lane the vehicle has to follow.
The traffic sign to keep to the right side of the lane is a red pillar. The traffic sign to keep to the left side of the lane is a green pillar. The vehicle is not allowed to move or knock down the traffic signs.
In order to turn the car around corners our team took advantage of the coloured strokes in the corners.
In order to detect the colours we used a TCS230 TCS3200D Colour Recognition Sensor.
We just need to convert the CMYK Colour Space to RGB and then differentiate between the orange and red.
The Orange colour- 255, 102, 0 (RGB)
The Blue colour- 0, 51, 255.
Not only that but the colours also help us to know whether to turn left or right depending on the one detected first.
To instruct the servo we used a conditional statement to check if any of the colours has been detected, if so we turn the servo 90 degrees for a few seconds.
if(bool(int(blue == NULL) & int(green == NULL))){
servo.write(180);
unsigned long cM3 = millis();
if(cM3 - pM3 > 5000){
pM3 = cM3;
servo.write(Sx);
}
counter = counter++;
}
When we were picking a method of steering the car it needed the following criteria:
-The amount of turning would depend on how far the car was from the wall.
-Fast and responsive.
We settled on proportional control.
The idea is lifted from PID control in control theory but in our case, we got away with the proportional control only.
The steering angle in our case is :
Steering angle = Proportional Gain * output
//Gain = Output(Servo)/Input(Distance(cm))
This is assuming the servo has a defined central position 50(degrees)
//Right
if(Right < 41 && Left > 41){
gain = float(Right)/41.0;
St = round(gain*50.0);
servo.write(round(St)+3);
}
The function for the left was treated differently as we are moving from the central position 50 towards 0(degrees). Thus the gain becomes:
gain = 41.0/float(Left);
St = round(gain*50.0);
The car is required to avoid the red and green pillars while moving to either side of the trock depending on the pillar colour.
The colour of the red traffic signs is RGB (238, 39, 55). The colour of the green traffic signs is RGB (68, 214, 44).
First we need to detect the objects.
This is done with on OpenCv python program. We create a mask for the colours Green and Red respectively and the send an interrupt to the arduino if a specific colour has been detected.
#Range of RED(HSV 0 255 255)
up_r = np.array([178,255,255],np.uint8)#[180,255,255]
low_r = np.array([158,100,100],np.uint8)#[136,87,111]
mask_r = cv.inRange(hsv,low_r,up_r)
A 51,51 Kernel is then applied to make it easier to detect the colours.
Red_blur = cv.GaussianBlur(mask_r,(51,51),0)
To reduce noise we set a thereshold for the colours to be filtered.This greatly reduces errors!
#Threshold the blurred mask(GREEN)
t,R_Thresh = cv.threshold(Red_blur,50,255,cv.THRESH_BINARY)