https://guitar.ucsd.edu/maeece148/api.php?action=feedcontributions&user=Winter2018group2&feedformat=atomMAE/ECE 148 - Introduction to Autonomous Vehicles - User contributions [en]2022-01-19T08:49:14ZUser contributionsMediaWiki 1.29.0https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=379Project gps2018-04-10T04:26:26Z<p>Winter2018group2: /* Bearing Calculation */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &phi;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
A great introduction to Donkey Car parts from the developers can be found '''[https://www.youtube.com/watch?v=YZ4ESrtfShs&t=150s here]''' and '''[https://www.youtube.com/watch?v=G1JjAw_NdnE here]'''. It is '''HIGHLY RECOMMENDED''' that you watch these videos first to save time later.<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, write data to a textfile, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action '''[https://www.youtube.com/watch?v=O6DhMk9fdZ4 here]'''.<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=378Project gps2018-04-10T04:26:05Z<p>Winter2018group2: /* Bearing Calculation */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &phi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
A great introduction to Donkey Car parts from the developers can be found '''[https://www.youtube.com/watch?v=YZ4ESrtfShs&t=150s here]''' and '''[https://www.youtube.com/watch?v=G1JjAw_NdnE here]'''. It is '''HIGHLY RECOMMENDED''' that you watch these videos first to save time later.<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, write data to a textfile, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action '''[https://www.youtube.com/watch?v=O6DhMk9fdZ4 here]'''.<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=337Project gps2018-03-25T20:25:21Z<p>Winter2018group2: /* Methods */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
A great introduction to Donkey Car parts from the developers can be found '''[https://www.youtube.com/watch?v=YZ4ESrtfShs&t=150s here]''' and '''[https://www.youtube.com/watch?v=G1JjAw_NdnE here]'''. It is '''HIGHLY RECOMMENDED''' that you watch these videos first to save time later.<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, write data to a textfile, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action '''[https://www.youtube.com/watch?v=O6DhMk9fdZ4 here]'''.<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=336Project gps2018-03-25T19:52:59Z<p>Winter2018group2: /* Results */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
A great introduction to Donkey Car parts from the developers can be found '''[https://www.youtube.com/watch?v=YZ4ESrtfShs&t=150s here]''' and '''[https://www.youtube.com/watch?v=G1JjAw_NdnE here]'''. It is '''HIGHLY RECOMMENDED''' that you watch these videos first to save time later.<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action '''[https://www.youtube.com/watch?v=O6DhMk9fdZ4 here]'''.<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=335Project gps2018-03-25T16:17:50Z<p>Winter2018group2: /* Multi-threading */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
A great introduction to Donkey Car parts from the developers can be found '''[https://www.youtube.com/watch?v=YZ4ESrtfShs&t=150s here]''' and '''[https://www.youtube.com/watch?v=G1JjAw_NdnE here]'''. It is '''HIGHLY RECOMMENDED''' that you watch these videos first to save time later.<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=334Project gps2018-03-25T16:17:26Z<p>Winter2018group2: /* Multi-threading */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
A great introduction to Donkey Car parts from the developers can be found '''[https://www.youtube.com/watch?v=YZ4ESrtfShs&t=150s here]''' and '''[https://www.youtube.com/watch?v=G1JjAw_NdnE here]'''. It is '''HIGHLY RECOMMENDED''' these videos first to save time in the future.<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=333Project gps2018-03-25T16:17:10Z<p>Winter2018group2: /* Multi-threading */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
A great introduction to Donkey Car parts from the developers can be found '''[https://www.youtube.com/watch?v=YZ4ESrtfShs&t=150s here]''' and '''[https://www.youtube.com/watch?v=G1JjAw_NdnE here]'''. It is '''HIGHLY RECOMMENDED these videos first to save time in the future.<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=332Project gps2018-03-25T16:13:42Z<p>Winter2018group2: /* Summary */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. Manages list of waypoints and stop conditions.<br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=331Project gps2018-03-25T16:13:21Z<p>Winter2018group2: /* Summary */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Threaded Donkey Car part that reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Donkey Car part that takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=330Project gps2018-03-25T16:12:32Z<p>Winter2018group2: /* Summary */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=329Project gps2018-03-25T16:12:09Z<p>Winter2018group2: /* Hardware Implementation */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
RX --> None<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=328Project gps2018-03-25T16:11:45Z<p>Winter2018group2: /* Hardware Implementation */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=327Project gps2018-03-25T16:08:28Z<p>Winter2018group2: /* Future Work */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Heading calculation issues<br />
** Because the bearing with respect to goal is calculated between the current and previous time step, small perturbations in the car trajectory (due to poorly tuned controllers, high speed, or difference in frequencies of main loop and threaded loop), can cause large deviations from the straight-line trajectory from start to goal.<br />
** Adjusting these parameters will improve performance.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=325Project gps2018-03-25T05:21:59Z<p>Winter2018group2: /* Results */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached. The second waypoint, Geisel Library, is not shown.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=324Project gps2018-03-25T05:21:00Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
==== Overview ====<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
==== Methods ====<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=323Project gps2018-03-25T05:19:48Z<p>Winter2018group2: /* Team Members */</p>
<hr />
<div>== Team Members ==<br />
Winter 2018<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=322Project gps2018-03-25T05:01:01Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
When the Planner loops through waypoints, the car will drive in a circle for X amount of time before continuing on to the next point.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=321Project gps2018-03-25T04:56:16Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.bearing<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=320Project gps2018-03-25T04:55:59Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''calc_bearing'''(self):<br />
''# calculate the bearing error using the process outlined in the bearing section above''<br />
return self.distance<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=319Project gps2018-03-25T04:51:06Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
''def'' '''drive_in_circle'''(self):<br />
''# send constant throttle and steering to drive in a circle once waypoint is reached''<br />
return throttle_cmd, steering_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=318Project gps2018-03-25T04:46:35Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=317Project gps2018-03-25T04:46:22Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=316Project gps2018-03-25T04:46:12Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
''def'' '''run'''(self):<br />
''# loop through waypoints, check for stop conditions, and call controllers''<br />
return steering_cmd, throttle_cmd<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement haversine formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=315Project gps2018-03-25T04:39:04Z<p>Winter2018group2: /* Multi-threading */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' '''__init__'''(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' '''run'''(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' '''shutdown'''(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' '''update'''(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' '''run_threaded'''(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement distance formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=314Project gps2018-03-25T04:38:35Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
<br />
''def'' '''update_distance'''(self):<br />
''# implement distance formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' '''steering_controller'''(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' '''throttle_controller'''(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=313Project gps2018-03-25T04:38:12Z<p>Winter2018group2: /* Planning Implementation: planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
The planner consists of two controllers: one for steering and one for throttle. At the moment, they are simply proportional controllers that take in their respective error signals and output a control signal. Future tuning of these controllers or implementation of a different controller altogether is suggested to improve the car performance.<br />
<br />
Here are the methods used in the planner class.<br />
<br />
''def'' update_distance(self):<br />
''# implement distance formula outlined in the distance section above''<br />
return self.distance<br />
<br />
''def'' steering_controller(self, currLocation, prevLocation)<br />
''# implement control algorithm based on bearing''<br />
return steering_cmd<br />
<br />
''def'' throttle_controller(self, currLocation):<br />
''# implement control algorithm based on distance to goal''<br />
return throttle_cmd<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=311Project gps2018-03-25T04:19:14Z<p>Winter2018group2: /* Bearing Calculation */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''def'' calc_bearing(self, pointA, pointB):<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=310Project gps2018-03-25T04:08:07Z<p>Winter2018group2: /* Methods */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) ''# GPStoRad converts parses GPS string to radians''<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=309Project gps2018-03-25T04:07:54Z<p>Winter2018group2: /* Methods */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation ''# update previous location''<br />
self.currLocation = self.GPStoRad(gpsdata) "# GPStoRad converts parses GPS string to radians"<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=308Project gps2018-03-25T04:05:48Z<p>Winter2018group2: /* Methods */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') ''# convert from byte to string''<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation "# update previous location"<br />
self.currLocation = self.GPStoRad(gpsdata) "# GPStoRad converts parses GPS string to radians"<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=307Project gps2018-03-25T04:05:26Z<p>Winter2018group2: /* Methods */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') "# convert from byte to string"<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation "# update previous location"<br />
self.currLocation = self.GPStoRad(gpsdata) "# GPStoRad converts parses GPS string to radians"<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
Poll is the main method called in the GPS class. It monitors the serial port, and converts the data from byte to string to float.<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=306Project gps2018-03-25T03:59:21Z<p>Winter2018group2: /* Methods */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' '''poll'''(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') "# convert from byte to string"<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation "# update previous location"<br />
self.currLocation = self.GPStoRad(gpsdata) "# GPStoRad converts GPS string to radians"<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=305Project gps2018-03-25T03:58:57Z<p>Winter2018group2: /* Methods */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
''def'' poll(self):<br />
gpsdataByte = self.gpsObj.readline() ''# read data from serial port''<br />
gpddata = gpsdataByte.decode('utf-8') "# convert from byte to string"<br />
if 'GPGGA' in gpsdata:<br />
self.prevLocation = self.currLocation "# update previous location"<br />
self.currLocation = self.GPStoRad(gpsdata) "GPStoRad converts GPS string to radians"<br />
else:<br />
pass<br />
return self.currLocation, self.prevLocation<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=304Project gps2018-03-25T03:58:22Z<p>Winter2018group2: /* Future Work */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.<br />
* Create an APP to set waypoints and destination and plan a route.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=303Project gps2018-03-25T03:46:47Z<p>Winter2018group2: /* planner.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
=== Planning Implementation: planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=302Project gps2018-03-25T03:46:25Z<p>Winter2018group2: /* gps.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== GPS Interfacing: gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=301Project gps2018-03-25T03:45:14Z<p>Winter2018group2: /* Multi-threading = */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== gps.py ===<br />
<br />
==== Multi-threading ====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
Instead of calling "run", Vehicle.py will call "update" while the flag self.on is "on". <br />
<br />
(3) When adding the part to the Vehicle.py use the following syntax:<br />
V.add(gps, outputs=[], inputs=[], '''threaded=True''')<br />
<br />
==== Methods ====<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=300Project gps2018-03-25T02:21:10Z<p>Winter2018group2: /* gps.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== gps.py ===<br />
<br />
==== Multi-threading =====<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
==== Methods ====<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=299Project gps2018-03-25T02:06:41Z<p>Winter2018group2: /* gps.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== gps.py ===<br />
<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation '''[https://docs.python.org/3/library/threading.html here]'''.<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
while self.on:<br />
''# call methods that you would like to run in the thread''<br />
<br />
''def'' run_threaded(self, ...):<br />
return output1, output2<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=298Project gps2018-03-25T02:04:07Z<p>Winter2018group2: /* gps.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== gps.py ===<br />
<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation [https://docs.python.org/3/library/threading.html here].<br />
<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=297Project gps2018-03-25T02:03:41Z<p>Winter2018group2: /* gps.py */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== gps.py ===<br />
<br />
gps.py is a '''threaded''' donkey car part. This allows us to run our gps polling method in parallel to the Donkey Car Vehicle.py loop.<br />
<br />
For more information on multi-threading in Python, see the official documentation [https://docs.python.org/3/library/threading.html here].<br />
<br />
Adding threaded functionality to Donkey Car parts is a very simple process.<br />
<br />
(1) First, define a Donkey Car part (python class) with the following methods:<br />
''def'' __init__(self, ...):<br />
''# initialize any attributes for the class''<br />
<br />
''def'' run(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
''def'' shutdown(self, ...):<br />
''# shutdown function when Vehicle.py exits loop''<br />
<br />
(2) To define a process as threaded, add the following two methods to the class:<br />
<br />
''def'' update(self, ...):<br />
''# main function that will be called in each loop of Vehicle.py''<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=296Project gps2018-03-25T01:53:16Z<p>Winter2018group2: /* Bearing Calculation */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
''# extract lat and long coordinates''<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialBeading = arctan2(x, y) ''# bearing (deg)''<br />
compassBearingRad = (initialBearing + 2*pi) % (2*pi)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=295Project gps2018-03-25T01:49:26Z<p>Winter2018group2: /* Future Work */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
extract lat and long coordinates<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialHeading = arctan2(x, y)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==<br />
<br />
* Implement a better control algorithm for improved steering performance.<br />
* Timing Issues<br />
** Default loop frequency for Vehicle.py is 20Hz, consider changing refresh rate.<br />
** Threaded GPS part updates GPS location slowly, consider different baud rates.</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=294Project gps2018-03-24T23:40:07Z<p>Winter2018group2: /* Team Members */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Yu-Chia Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
extract lat and long coordinates<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialHeading = arctan2(x, y)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=293Project gps2018-03-24T23:39:25Z<p>Winter2018group2: /* Results */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Sidney Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
extract lat and long coordinates<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialHeading = arctan2(x, y)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
You can see the car LIVE in action here: https://www.youtube.com/watch?v=O6DhMk9fdZ4<br />
<br />
== Future Work ==</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=292Project gps2018-03-24T23:33:50Z<p>Winter2018group2: /* Results */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Sidney Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
extract lat and long coordinates<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialHeading = arctan2(x, y)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
<iframe width="560" height="315" src="https://www.youtube.com/embed/O6DhMk9fdZ4?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe><br />
<br />
== Future Work ==</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=291Project gps2018-03-24T23:33:13Z<p>Winter2018group2: /* Hardware Implementation */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Sidney Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP's TX to the pi's RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
extract lat and long coordinates<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialHeading = arctan2(x, y)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
== Future Work ==</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=290Project gps2018-03-24T23:32:02Z<p>Winter2018group2: /* Hardware Implementation */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Sidney Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP’s TX to the pi’s RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
[[File:pc2.png]]<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
extract lat and long coordinates<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialHeading = arctan2(x, y)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
== Future Work ==</div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=File:Pc2.png&diff=289File:Pc2.png2018-03-24T23:31:38Z<p>Winter2018group2: </p>
<hr />
<div></div>Winter2018group2https://guitar.ucsd.edu/maeece148/index.php?title=Project_gps&diff=288Project gps2018-03-24T23:30:37Z<p>Winter2018group2: /* Hardware Implementation */</p>
<hr />
<div>== Team Members ==<br />
* Matthew Gilli, Electrical Engineering B.S.<br />
* Sidney Hsu, Mechanical Engineering M.S.<br />
* Jason Mayeda, Mechanical Engineering B.S.<br />
* Roy Sun, Mechanical Engineering B.S.<br />
<br />
== GPS and Autonomous Vehicles ==<br />
Global Positioning System (GPS) is formed by a network of satellites that provides geolocation data (time stamps, coordinates) to compatible GPS receivers. GPS data is commonly used along with a suite of other sensors in autonomous systems for navigation and control. The data provides coordinates in a global coordinate frame (latitude, longitude) that can be used to perform simply point-to-point navigation tasks. For more information about GPS fundamentals, see [https://www.gps.gov/systems/gps/ GPS.gov.].<br />
<br />
== Project Overview ==<br />
Due to complications with previous plug-and-play GPS modules for DonkeyCar autonomous vehicles, we sought to build our own DonkeyCar-compatible GPS module from scratch. The main flow of our project is as follows:<br />
<br />
# Initialize a list of waypoints.<br />
# Recieve GPS data from GP-20U7 reciever.<br />
# Determine current position and bearing of the car with respect to the waypoint.<br />
# Calculate throttle and steering commands to direct the car to the waypoint.<br />
# Repeat steps 2-4 until the waypoint is reached.<br />
# Once the car reaches a waypoint, drive in circle for X amount of time.<br />
# Repeat steps 2-6 until all waypoints in the list have been visited.<br />
<br />
This project was implemented with two main processes: planning and GPS interface.<br />
<br />
<br />
'''GPS Interface'''<br />
* Polls for GPS data through the Pi serial port. <br />
* Parses GPS strings for relevant coordinate and time data.<br />
* Inputs: Bit/s<br />
* Outputs: Car location: GPS coordinates in latitude and longitude.<br />
<br />
'''Planner'''<br />
* Implements control algorithms to calculate actuator commands for the car.<br />
* Keeps track of additional stop conditions.<br />
* Manages waypoint list.<br />
* Inputs: Car location: GPS coordinates in latitude and longitude<br />
* Outputs: Throttle and steering commands<br />
<br />
== Hardware Implementation ==<br />
To implement our navigation tasks, we used the inexpensive GP-20U7 GPS receiver. [https://www.sparkfun.com/products/13740 Here] you can find more information on the receiver including cost, sample projects, and a data sheet. <br />
<br />
An embedded system is a system with dedicated function within larger system. <br />
<br />
The gps system was embedded into car system<br />
<br />
In order for gps to communicate with car they must share a common communication protocol. In this case, serial communication.<br />
<br />
Serial interfaces stream their data, one single bit at a time. These interfaces can operate on as little as one wire, usually never more than four. A serial bus consists of just two wires - one for sending data and another for receiving. As such, serial devices should have two serial pins: the receiver, '''RX''', and the transmitter, '''TX'''.<br />
<br />
[[File:pc1.png]]<br />
<br />
It's important to note that those RX and TX labels are with respect to the device itself. So the RX from one device should go to the TX of the other, and vice-versa. <br />
<br />
Some serial busses might get away with just a single connection between a sending and receiving device. In our case, the RPI does not need to relay any data back to the GPS. All that is needed is a single wire from the GP’s TX to the pi’s RX<br />
An example of this is shown in wiring diagram below.<br />
<br />
'''PIC 2'''<br />
<br />
<br />
To connect the GPS unit to the Pi, follow these pinout instructions:<br />
<br />
GP-20U7 --> Pi<br />
VCC --> 3V<br />
GND --> GND<br />
TX --> RX<br />
<br />
== Software Implementation ==<br />
<br />
=== Summary ===<br />
Main<br />
<br />
'''gps_manage.py'''<br />
<br />
Our GPS analog to the Donkey Car manage.py. Add parts to the DK vehicle and calls Vehicle.py.<br />
<br />
Dependent libraries: <br />
<br />
DonkeyCar, time, threading<br />
<br />
<br />
DonkeyCar Parts<br />
<br />
'''gps.py'''<br />
<br />
Reads GPS data from the Pi serial port. Waits for identifier in strings to parse relevant GPS data (latitude, longitude coordinates).<br />
<br />
Dependent libraries: <br />
<br />
numpy, serial, [https://github.com/Knio/pynmea2 pynmea2]<br />
<br />
<br />
'''planner.py'''<br />
<br />
Takes GPS coordinates of current and previous time step to calculate distance and bearing to goal. Uses distance and bearing data to calculate the throttle and steering commands, respectively. <br />
<br />
Dependent libraries: <br />
<br />
numpy, time<br />
<br />
=== Mathematical Equations ===<br />
<br />
==== Distance Calculation ====<br />
<br />
Our distance equations were based on the haversine derivations on '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''. <br />
<br />
A Python implementation of the haversine equation can be found in our planner.py part.<br />
<br />
==== Bearing Calculation ====<br />
<br />
[[File:GPS.jpg | 600 px]]<br />
<br />
Important Parameters:<br />
<br />
# Calculate the bearing &theta;<sub>i</sub> of the vector made by the current location and the goal point, with respect to North.<br />
# Calculate the bearing &psi;<sub>i</sub> of the vector made by the previous time step location and the current location, with respect to North.<br />
<br />
Method:<br />
<br />
Our bearing calculation method is outlined at '''[https://www.movable-type.co.uk/scripts/latlong.html this page]'''.<br />
<br />
Also included on this page is sample JavaScript implementation of all of the equations.<br />
<br />
Sample code:<br />
extract lat and long coordinates<br />
lat1 = pointA[0]<br />
lon1 = pointA[1]<br />
lat2 = pointB[0]<br />
lon2 = pointB[1]<br />
<br />
diffLon = lon2 - lon1<br />
x = sin(diffLon) * cos(lat2)<br />
y = cos(lat1) * sin(lat2) - (sin(lat1)*cos(lat2)*cos(diffLon))<br />
<br />
initialHeading = arctan2(x, y)<br />
<br />
=== gps.py ===<br />
<br />
=== planner.py ===<br />
<br />
== Results ==<br />
[[File:trajectory.png|750px]]<br />
<br />
Results of a typical two point waypoint navigation. The starting point is shown in black. The first waypoint, "Warren Mall", is shown in red. The threshold goal circle surrounding the waypoint is shown as the dashed circle. The graph shows that the car did trigger the "drive in circle" method once the goal threshold was reached.<br />
<br />
== Future Work ==</div>Winter2018group2