F12: Self-Driving GPS Following Car
Contents
- 1 Self-Driving GPS Following Car
- 2 Abstract
- 3 Introduction and Objectives
- 4 Team Members and Responsibilities
- 5 Schedule
- 6 Parts List & Cost
- 7 Design & Implementation
- 8 Testing & Technical Challenges
- 9 Conclusion
- 10 References
Self-Driving GPS Following Car
Abstract
The objective of this project is to create an autonomous vehicle that follows another car. A leading car will continually inform the autonomous car of its location. The autonomous car will then drive to the target location while avoiding obstacles along the way.
Introduction and Objectives
The Self-Driving GPS Following Car follows another car by driving to the GPS coordinates of the leading car. A ZigBee communication link transmits the GPS data from the leading car to the following car. The following car utilizes a GPS and a compass to determine its own location and orientation relative to magnetic north. Using the two pairs of GPS coordinates and the orientation of the car, the bearing and distance necessary to be traveled is calculated. The car uses proximity sensors, so the car can avoid obstacles while navigating to the destination.
The project required the following objectives to be accomplished:
- Read GPS coordinates of the leading car and the following self-driving car
- Use XBee modules to send and receive GPS coordinates from the leading car to the following car
- Compute the true north bearing and distance necessary for the following car to reach the leading car
- Account for difference between true north and magnetic north in bearing calculation
- Read the magnetic north bearing using a compass
- Read the distance to objects using proximity sensors
- Control steering motor to steer left, right, and straight using a motor controller
- Control direction motor to move forward, backward, and stop using a motor controller
- Determine algorithm to drive toward destination
- Determine algorithm to avoid obstacles
Team Members and Responsibilities
- Elias Barboza
- PWM driver, motor controllers, and obstacle avoidance
- Caleb Chow
- Read compass, read GPS coordinates, and move toward target GPS coordinates
- Stephen Lu
- ADC driver, read proximity sensors, compute distance based on measurement, and obstacle avoidance
Schedule
Week Number | Planned Items | Actual Items |
---|---|---|
Week 1: Design
|
|
|
Week 2: Construction
|
|
|
Week 3: Drivers
|
|
|
Week 4: Coding
|
|
|
Week 5: Coding
|
|
|
Week 6: Testing
|
|
|
Week 7: Finalization
|
|
|
Parts List & Cost
Parts | Quantity | Cost | Link |
---|---|---|---|
RC Car -
| 2 | ~$25 | Previously owned |
Microcontroller -
| 1 | ~$120 | |
XBee Module -
| 2 | ~$24.95 |
|
GPS -
| 2 | $37.21 | |
Motor Controller -
| 2 | ~$13 | |
Compass -
| 1 | $50 | |
Sonar Range Finder -
| 3 | $26.95 | |
Design & Implementation
Hardware Design
Leading Car
The leading car consists of the following additional hardware:
- XBee module
- GPS module
- 3.3V regulator circuit
The leading car is responsible for sending its GPS coordinates to the following car. This is accomplished by sending the raw GPS data over ZigBee to the following car. The GPS and XBee modules both use UART to communicate, so no microcontroller is necessary. The paired XBee modules will take care of the data transfer. Both modules ran off the same 3.3V power supply, which came from a regulator off of the car’s battery pack.
Following Car
The following car consists of the following additional hardware:
- SJ One board
- XBee module
- GPS module
- 2x Motor controllers
- Compass
- 3x proximity sensors
- 5 cells of AA battery pack
- 5V regulator circuit
- Power switch
The following car is responsible for avoiding obstacles and for driving to a destination coordinate. To accomplish this, the car needs to know its own location, the target coordinate, information about its surroundings, and be able to move. Its own location was determined using a GPS and a compass, while the target coordinate was received from the leading car over ZigBee. Proximity sensors were used to get information about its surroundings and motor controllers enabled control over the motors. A microcontroller was used to control all the peripheral devices. The compass and the motor controllers required a regulated 5V power supply, which came from a 5V regulator off of the car’s battery pack, while the microcontroller could take anywhere between around 4.5V to 9V, which came straight off of the car’s battery pack. The remaining devices took 3.3V, which came regulated from the microcontroller. The 5V regulator required a voltage higher than 5V, which resulted in the car’s battery pack being upgraded to five cells of AA batteries.
Hardware Interface
Leading Car
The following table shows the pin connections for the XBee module to send the GPS module's data to the receiving end of the XBee.
GPS to XBee Pin Connections
GPS Pin | XBee Pin |
---|---|
TX | RX |
Following Car
The following table shows the pin connections for the SJ One board to communicate with the peripherals.
SJ One Board Pin Connections
SJ One Board Pin | Destination Pin | Description |
---|---|---|
UART2 RX | GPS TX | GPS data received for following car |
UART3 RX | XBee TX | GPS data received using XBee for leading car |
I2C2 SDA | Compass SDA | Serial data |
I2C2 SCL | Compass SCL | Serial clock |
ADC0-3 / ADC0-out | Front proximity sensor analog out | Analog distance reading for front sensor |
ADC0-4 | Left proximity sensor analog out | Analog distance reading for left sensor |
ADC0-5 | Right proximity sensor analog out | Analog distance reading for right sensor |
GPIO P1.24 | Steering motor enable | Set steering amount |
GPIO P1.25 | Steering motor dir1 | Set steering direction |
GPIO P1.22 | Steering motor dir2 | Set steering direction |
PWM1-2 | Direction motor enable (PWM) | Set speed |
GPIO P1.19 | Direction motor dir1 | Set motor direction |
GPIO P1.23 | Direction motor dir2 | Set motor direction |
The GPS and XBee both communicated with the microcontroller using UART while the compass used I2C. There were no other alternatives that could be selected on the modules.
The three proximity sensors on the other hand had a selection of three outputs to choose from: UART, analog, or PWM. Since the UARTs and PWMs were all taken, analog outputs were selected to be used for the sensors.
A PWM and GPIOs were used to control the motors. The PWM was used to control the speed of the direction motor and GPIOs were used for the direction. The steering motor did not require a PWM since setting the amount to steer left or right was not necessary. The signals to the motor controllers were set using the logic table below to enable steering and direction movement.
Motor Controller Logic Table
Enable | Dir1 | Dir2 | Direction Motor | Steering Motor |
---|---|---|---|---|
H | H | H | Brake | Steer straight |
H | L | L | Brake | Steer straight |
H | H | L | Rotate forward direction | Steer left |
H | L | H | Rotate backward direction | Steer right |
L | X | X | Coast | Steer straight |
Software Design
The project was built on top of the FreeRTOS sample project with the UART, I2C, and ADC drivers included. Additional tasks were created to enable multitasking.
Tasks
The following tasks were used on the self-driving car:
- Terminal Task
- Handles commands to get system information and set runtime configurations for logging and navigation options
- XBee GPS Task
- Reads and processes GPS data through XBee module to keep coordinates of the leading car updated
- My GPS Task
- Reads and processes own GPS data to keep own coordinates updated
- Sensors Task
- Keeps own heading relative to magnetic north updated
- Keeps distances from objects in front, to the left, and to the right of the car updated
- Navigation Task
- Uses motor controllers to drive
- Uses distances from objects to avoid obstacles
- Uses its own and the leading car's GPS coordinates to compute necessary heading to travel at to reach destination
- Uses compass heading and required heading to align itself to destination
- Info Task
- Handles logging of own GPS and XBee GPS readings, sensor readings, and navigation information
The tasks were created such that the GPS tasks have a higher priority than the rest. Since GPS data was stored into a buffer by UART, the data could not be allowed to collect or else by the time the car updates the coordinates, the data will already by outdated. The tasks were also designed with different sleep delays. The GPS tasks had no delay since they will automatically sleep when there is no data to read, while the sensors task had a delay of 75mS. The bare minimum allowed was 49mS, which was limited by the proximity sensors. Additional delay was added for safe measure to prevent reading echos. The navigation task was set to have a delay of 50mS. A delay less than the sensors was selected so that the worst case time before readjusting the motors to the driving conditions was 125mS. This would allow the car to have a faster reaction time.
In order to allow data to be accessed by multiple tasks, certain variables had to be made accessible globally. This was accomplished by using handles to the data. For the data that had to be updated simultaneously, such as GPS coordinates, a semaphore was used to lock the data. Integers that had to be shared were not required to be locked since the variables could be updated with a single instruction.
GPS Data Handling
The two GPS tasks processed GPS data identically. GPS data was received following the National Marine Electronics Association (NMEA) specifications. Since the only necessary information to read was latitude and longitude, sentences of type GGA were selected to be processed so that the coordinates could be stored for use in navigation.
In the navigation task, computations had to be made to get from having two sets of GPS coordinates to knowing how to steer toward the destination. NMEA sentences store the coordinates in a degree-decimal minute format (DDDMM.MMMM). In order to make use of the coordinates for distance and bearing calculations, the coordinates have to be converted to decimal degree format (DDD.DDDD). Trigonometry can be used with the coordinates in decimal degree format to compute the distance and bearing necessary. But, the bearing computed is relative to the true north while the compass reading is relative to magnetic north. Since magnetic north is constantly changing depending on the geographical location, the difference, or magnetic declination, needs to be accounted for. The end result of all the computation is the target angle desired to be read on the compass, which indicates the direction of the destination.
Obstacle Avoidance
Obstacle avoidance was accomplished by using the distances read from the proximity sensors. The following flowchart shows the algorithm used to avoid obstacles.
Hardware Implementation
All of the components are interfaced through the SJOneboard which has a built-in LPC1758 Microcontroller. The three sonar sensors provide their data readings through ADC as voltage values, which are interpreted accordingly in software, based on their datasheet specifications. There are two motor controllers in the system, one for each motor in the car. The rear motor and its controller is manipulated with PWM, which enables for changes in speed. The PWM is connected to the enable pin in the motor controller to save battery and for better control of the motor. The front motor controller is always enabled since the motor is not used very often. Each motor controller has two direction pins, thus all four pins are connected to four GPIO ports on the main SJOne board. The last two components, the GPS and Compass are connected to the board through I2C and ADC, respectively.
The photos below show our hardware implementation.
Software Implementation
Terminal Task
In order to simplify development, a configuration utility was used. The configuration utility allowed for calibrations to be made without reprogramming the microcontroller. This allowed for faster testing and calibration of the sensors, motor speed, and logging without having to rebuild every time. The configuration utility also allowed us to log sensor information in order to know the readings when the car was not connected directly to the terminal and it was in motion. The utility modifies the program variables directly in the flash memory with the use of specific terminal commands.
XBee GPS and My GPS Tasks
All this task did was process the received GPS data from UART into a latitude and longitude coordinate. A NMEA sentence was verified to be valid by checking the checksum. Once the sentence was verified, the fields were parsed to get the coordinates.
Sensors Task
The sensors task used I2C to read compass data and ADC to read the proximity sensors. A compass reading was made by reading two bytes. A high byte register and low byte register was read and combined to create the reading. The data was then converted to the standard 360 degree format. Proximity sensor readings were made by reading the analog output from the sensor. The value was compared to the supply voltage to determine how much of the maximum range an object was at.
In order to drive the car, the navigation task used sensor readings and navigation information to control the motor controllers. The motor controllers were controlled by using a PWM to set the motor speed and GPIO pins to set the motor directions. Speeds and directions were determined by checking distances from objects, whose thresholds could be configured. Objects at different thresholds would make the car react differently. When there were no obstacles, car would drive toward the destination by calculating the bearing needed to get from the starting GPS coordinate to the destination GPS coordinate. Under drive to destination condition, the car would steer to align its bearing with the required bearing and drive forward.
Info Task
The info task uses the configuration utility to determine what information to log and whether to log to the flash memory or just display it. Sensor readings and navigation information were all capable of being logged.
Testing & Technical Challenges
Sensor Thresholds
Values needed to be determined for a number of thresholds. The thresholds were front detect, front backup, side detect, and side backup. The detect thresholds trigger the car to slow down and the backup thresholds trigger the car to backup.
We spent quite a bit of time figuring out the perfect front threshold. We needed to figure out the best values for these thresholds. We don’t want the thresholds to be too small so that the car doesn’t have enough space to slow down, stop, and backup. We also do not want the thresholds to be too large so that the car is always backing up when it has room to turn away from the obstacle.
Sound Reflections
The proximity sensors are ultrasonic, meaning they send out a sound wave and calculate how much time it takes for the reflected echo to come back. However, when our following car is in a corner, the sound waves might not reflect back to the source sensor, but to the other two sensors, making the car backup or turn unnecessarily.
To fix this problem, we would need more sensors to detect a larger radius and also a more descriptive picture of the obstacle. However, due to limited ADC pins we were only able to use a maximum of three sensors.
Compass Interference
The LSM303DLM compass uses the Earth’s magnetic field to determine the direction it is facing. Therefore, the compass has to be at least 6 inches away from any magnet, according to the datasheet. The GPS module on the car uses a magnet as its antenna so we knew we had to mount our compass, as explained in our hardware implementation section.
The interference became a problem when we were testing the compass indoors. There are a lot of sources of magnetic fields inside classrooms from computers. When we hard coded the car to always go north (0 degrees), the car will start going in one direction, before turning around and heading off to a different location. This problem will be solved when we test our car outdoors.
GPS Accuracy
Our GPS modules work the best outdoors. The GPS modules take a while to boot up, around 45 seconds to a minute. While testing outdoors, we connected our car via USB to Hercules until we received the GPS signal. Then, we unplugged the car but still left the car on so the GPS doesn’t shut off. We verified the GPS coordinates by printing out the coordinates in Hercules and putting them into Google Maps. However, the GPS module on our leading car was not very accurate. When we place the two cars next to each other, the coordinates are not the same, and differ by around 15 meters.
Power Consumption
We changed motor controllers around halfway through the project. The old motor controllers needed at least 6V to be powered. A 9V battery drained too quickly to be suitable for actual testing and demonstration purposes. The next idea was to take the 4 AA batteries’ voltage and use a voltage booster to boost it up to the necessary voltage. After a week of testing, the voltage booster stopped working due to overheating and the regulator melting. Preet suggested to use a new motor controller, the current one used in the car. This one only needed 5V as the supply.
Another power consumption problem was the compass. It needed a minimum of 5V to power on. This means the 4 AA batteries that produce 4.8V is not enough to power the compass. Since the voltage booster stopped working, we needed another way to produce more voltage. To fix the problem, we added another AA to the battery pack to create 6V. This required breaking one of the tabs on the battery pack and soldering more metal tabs to it. Using 5 AA batteries allowed us to power our motor controllers, the compass and the LPC1758 board.
XBee Range
The range of the Xbee modules should be 400 feet according to the datasheets. When testing outdoors, the following car seemed to drive away from the leading car. To debug the problem, we connected the following car via USB to Hercules and read the GPS data from both cars. Then, one member of the team walks away from the computer with the lead car until the leading car GPS data becomes invalid or inconsistent. After testing, the range of the Xbee modules was only 40-50 feet.
Bad Front Sensor
When we bought our parts, we only bought two proximity sensors, one pointing towards the left, and the other pointing towards the right. After a discussion with Preet, he suggested to add a sensor pointing forward and he provided us one. This sensor used I2C and passes the distance detected in inches as data. However, the maximum distance measured by the sensor was only 24 inches, which is too small to be our front threshold. We were able to find a 3rd proximity sensor that was the same as the other two side sensors. This sensor could measure up to 254 inches and is sufficient enough for our thresholds.
Motor Speeds
The motor controllers output a PWM signal to control the motors. The higher the duty cycle, the faster the motor spins. However, this will consume more energy. The duty cycle must be high enough for the wheels to overcome the friction of the ground. During the testing phase, the car also produces a high pitch sound, indicating that the duty cycle is not high enough. With the old motor controllers, when the duty cycle too high, the batteries drained quickly. With the new motor controllers that are more efficient and use less power, the duty cycle can be set to the maximum of 100 without draining the battery quickly.
Another side-effect of a high duty cycle is the car will travel too fast and have less time to stop and avoid obstacles. To fix this problem, the front and side thresholds were increased to allow the car to stop and backup without hitting obstacles.
Conclusion
The GPS Following Car is, in general, an embedded system that connects together five different components that are interfaced together in software through protocols such as I2C, UART, and ADC.
The main objective of the project was to create a car that would be able to follow another car automatically by acquiring the necessary information from the leading car, such as GPS coordinates and heading.
The challenge of the project was for the following car to be able to travel to its destination by itself without colliding with any external objects. This challenge was tackled by following a very strict and efficient object-avoiding algorithm.
As a team of engineers, this project enhanced our programming skills by taking our knowledge of the C and C++ languages and putting them to use to ensuring that the system worked effectively and efficiently. We learned to communicate and share information with one another in a way that we were always productive and learned to manage our time effectively to make consistent progress throughout the semester.
Also, our understanding of operating systems was challenged in this project because the system as a whole is based on FreeRTOS. By having an actual O.S. run our system we were challenged to meet acceptable CPU efficiency levels, to make use of the available memory efficiently by limiting our tasks to only using the amount of stack necessary to execute.
Project Video
Project Source Code
References
Acknowledgements
Dr. Haluk Özemek
Preet Kang
References Used
Compute distance between coordinates: [1]
Compute bearing to get from one coordinate to another: [2]
Adjust bearing to magnetic bearing: [3]
Appendix
ZIP file: TODO