Here we have implemented Guided EV3 Car Parking. This car is a line follower which is implemented using a light sensor. The car follows the line and reaches the "statues" which indicate that there is an existence of car parking slot in front of them. The slots may be empty or occupied. Car intercepts these statues using an Infra-red sensor. Once the car intercepts a statue, it tries to find if there is a car already parked in front of the statue. Car recognizes this with the help of Ultrasonic sensor. If the parking is already occupied, the car moves on, in search of an empty parking. Once it finds an empty parking, the car parks itself in that parking place.
As you must have noticed, the three statues are erected in the left of the road (the thick black line) and the car parking is on the right of the road. The three statues, correspond to three parking slots. To intercept the statues, the infra-red sensor is mounted on the back-left of the car. While the ultrasonic sensor is mounted on the back-right of the car, to detect whether the parking slot is empty or a car is already parked on the slot. Once an empty car parking slot is detected, the car takes a right turn to park itself. The gyro sensor is mounted on the front-right of the car and helps the car to turn in 90 degrees.
NOTE: In order to understand the line follower mechanism, it would be good if you read the following article: EV3 Line Follower
Let me explain the program for guided car parking in more detail. The program is implemented in LeJOS programming language. We have a single class called CarkParking. The main method of the program begins with initializing the motors and the sensors. The four sensors, ultrasonic sensor, infrared sensor, color sensor and the gyro sensor are connected to ports S3, S1, S4, S2 respectively. They are initialized in Distance mode, Distance mode, Red mode and Angle mode respectively. The modes of all the sensors are almost self explanatory, except the Red mode of the color sensor. The Red mode returns the intensity of the reflected Red light from the black/white surface. On initializing all the sensors, the line follower program begins and we follow the following algorithm.
- Follow the line
- Check whether the infrared sensor sample is less than 30cm.
- If yes, we know that there is a statue present near the car. Then we go ahead and check if ultrasonic sensor sample is greater than 50 cm.
- If yes, we know that the car parking is empty. Then we go ahead and check if gyro sensor sample is greater than -90 degrees
- If yes, we keep taking a right turn until the gyro sensor sample reaches -90 degrees.
- If no, continue to follow the line
Assumption: This program assumes that the automated car is necessarily searching for car parking slot and does not want to continue driving on the road without any need for parking.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lejos.hardware.Button; | |
import lejos.hardware.Sound; | |
import lejos.hardware.lcd.LCD; | |
import lejos.hardware.motor.NXTMotor; | |
import lejos.hardware.port.MotorPort; | |
import lejos.hardware.port.SensorPort; | |
import lejos.hardware.sensor.EV3ColorSensor; | |
import lejos.hardware.sensor.EV3GyroSensor; | |
import lejos.hardware.sensor.EV3IRSensor; | |
import lejos.hardware.sensor.EV3UltrasonicSensor; | |
import lejos.hardware.sensor.SensorMode; | |
import lejos.robotics.SampleProvider; | |
import lejos.utility.Delay; | |
public class CarParking { | |
public static void main(String[] args) { | |
// TODO Auto-generated method stub | |
//Initialize color sensor | |
EV3ColorSensor colorSensor = new EV3ColorSensor(SensorPort.S4); | |
SensorMode mode = colorSensor.getRedMode(); | |
//Initialize gyro sensor | |
EV3GyroSensor gSensor = new EV3GyroSensor(SensorPort.S2); | |
gSensor.reset(); | |
//Initialize ultrasonic sensor | |
EV3UltrasonicSensor ultra = new EV3UltrasonicSensor(SensorPort.S3); | |
//Initialize IR sensor | |
EV3IRSensor irSensor = new EV3IRSensor(SensorPort.S1); | |
SampleProvider provider1 = ultra.getDistanceMode(); | |
SampleProvider provider2 = gSensor.getAngleMode(); | |
SampleProvider provider = irSensor.getDistanceMode(); | |
//Get the White color sample | |
Sound.twoBeeps(); | |
LCD.drawString("white", 0, 0); | |
Button.ESCAPE.waitForPressAndRelease(); | |
float[] sampleWhite = new float[1]; | |
mode.fetchSample(sampleWhite, 0); | |
LCD.drawInt(new Float(sampleWhite[0] * 100).intValue(), 2, 2); | |
//Get the Black color sample | |
Delay.msDelay(1000); | |
Sound.twoBeeps(); | |
LCD.drawString("Black", 4, 4); | |
Button.ESCAPE.waitForPressAndRelease(); | |
float[] sampleBlack = new float[1]; | |
mode.fetchSample(sampleBlack, 0); | |
LCD.drawInt(new Float(sampleBlack[0] * 100).intValue(), 6, 6); | |
Delay.msDelay(3000); | |
//Set the default power and the multiplying factor for the line follower | |
int defaultPower = 30; | |
int multiplyingFactor = 50; | |
//Initialize motors | |
NXTMotor largeMotorB = new NXTMotor(MotorPort.B); | |
NXTMotor largeMotorC = new NXTMotor(MotorPort.C); | |
float[] color = new float[1]; | |
float[] sample = new float[1]; | |
float[] sample1 = new float[1]; | |
float[] sample2 = new float[1]; | |
while (!Button.ESCAPE.isPressed()) { | |
//Line Follower algorithm starts | |
float avgLight = (sampleBlack[0] + sampleWhite[0]) / 2; | |
mode.fetchSample(color, 0); | |
float cSpeed = defaultPower + multiplyingFactor | |
* (avgLight - color[0]) / (sampleWhite[0] - sampleBlack[0]); | |
largeMotorC.setPower(new Float(cSpeed).intValue()); | |
largeMotorC.forward(); | |
float bSpeed = defaultPower - multiplyingFactor | |
* (avgLight - color[0]) / (sampleWhite[0] - sampleBlack[0]); | |
largeMotorB.setPower(new Float(bSpeed).intValue()); | |
largeMotorB.forward(); | |
//Line Follower algorithm ends | |
//While following the line, fetch the IR sensor sample | |
provider.fetchSample(sample, 0); | |
LCD.drawInt(new Float(sample[0]).intValue(), 1, 1); | |
//Check if IR sensor sample is less than 30cm (which indicates the existance of statues) | |
if (sample[0] < 30) { | |
provider1.fetchSample(sample1, 0); | |
LCD.drawInt(new Float(sample1[0]).intValue(), 5, 5); | |
//Check if ultrasonic sensor samples are less than 50cm (which indicates an empty slot) | |
if (sample1[0] > 0.5) { | |
provider2.fetchSample(sample2, 0); | |
LCD.drawInt(new Float(sample2[0]).intValue(), 7, 7); | |
//Start parking the car by turning it, until the gyro sensor samples are greater than -90 | |
while (sample2[0] > -90 && !Button.ESCAPE.isPressed()) { | |
largeMotorB.setPower(40); | |
largeMotorC.setPower(40); | |
largeMotorB.forward(); | |
largeMotorC.backward(); | |
provider2.fetchSample(sample2, 0); | |
LCD.drawInt(new Float(sample2[0]).intValue(), 7, 7); | |
} | |
//Once car turns 90 degrees for parking, drive more for 5 seconds and stop the car. | |
largeMotorB.setPower(40); | |
largeMotorC.setPower(40); | |
largeMotorB.forward(); | |
largeMotorC.forward(); | |
Delay.msDelay(5000); | |
break; | |
} | |
} | |
} | |
} | |
} |
No comments:
Post a Comment