Using a GPS system

The Global Positioning System (GPS) is a space-based satellite system that provides information on the position and time for any weather and any place on the face of the earth and its vicinity. You must have an unobstructed direct path with four GPS satellites to obtain valid data.

The data received from the GPS conforms to the standards of communication set up by National Maritime Electronics Association (NMEA) and follows a protocol with different types of sentences. In them, we can find all the information about the position of the receiver.

Note

To read more about all the types of NMEA messages, you can visit http://www.gpsinformation.org/dale/nmea.htm.

One of the most interesting pieces of information about GPS is contained in GGA sentences. They provide the current fix data with the 3D location of the GPS. An example of this sentence and an explanation of each field is given here:

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
Where:
GGA Global Positioning System Fix Data
123519 Fix taken at 12:35:19 UTC
4807.038,N Latitude 48 deg 07.038' N
01131.000,E Longitude 11 deg 31.000' E
1 Fix quality: 0 = invalid
1 = GPS fix (SPS)
2 = DGPS fix
3 = PPS fix
4 = Real Time Kinematic
5 = Float RTK
6 = estimated (dead reckoning) (2.3 feature)
7 = Manual input mode
8 = Simulation mode
08 Number of satellites being tracked
0.9 Horizontal dilution of position
545.4,M Altitude, Meters, above mean sea level
46.9,M Height of geoid (mean sea level) above WGS84
ellipsoid
(empty field) time in seconds since last DGPS update
(empty field) DGPS station ID number
*47 the checksum data, always begins with *

Depending on the GPS receiver, we can find different performances and precisions. We have a simple GPS at a low cost that is commonly used in different applications, such as UAV. They have an error that can be in the range of a few meters. Also, we can find expensive GPS devices that can be configured as differential GPS or can work in the Real Time Kinematics (RTK) mode, where a second GPS at a known location sends corrections to the first GPS. This GPS can achieve great results in terms of precision, with location errors less than 10 cm.

In general, GPS uses serial protocols to transmit the data received to a computer or a microcontroller, such as Arduino. We can find devices that use TTL or RS232, and they are easy to connect to the computer with a USB adapter. In this section, we will use a low-cost NEO-Bloc 6 M and a really accurate system, such as GR-3 Topcon in the RTK mode. We will see that, with the same drivers, we can obtain the latitude, longitude, and altitude from both devices:

Using a GPS system

Em406a and Topcon GPS

In order to control a GPS sensor with ROS, we will install the NMEA GPS driver package by using the following command line (don't forget to run the rosstack and rospack profiles after that):

$ sudo apt-get install ros-kinetic-nmea-gps-driver
$ rosstack profile & rospack profile

To execute the GPS driver, we will run the nmea_gpst_driver.py file. To do that, we have to indicate two arguments: the port that is connected to the GPS and the baud rate:

$ rosrun nmea_gps_driver nmea_gps_driver.py _port:=/dev/ttyUSB0 _baud:=4800

In the case of the EM-406a GPS, the default baud rate is 4800 Hz as indicated in the preceding command line. For Topcon GR-3, the baud rate is higher; it's about 1,15,200 Hz. If we want to use it with ROS, we will modify the _baud argument, as shown in the following command:

$ rosrun nmea_gps_driver nmea_gps_driver.py _port:=/dev/ttyUSB0 _baud:=115200

How GPS sends messages

If everything is OK, we will see a topic named /fix in the topic list by typing this:

$ rostopic list

To know which kind of data we will use, we typed the rostopic command. The NMEA GPS driver uses the sensor_msgs/NavSatFix message to send the GPS status information:

$ rostopic type /fix
sensor_msgs/NavSatFix

The /fix topic is sensor_msg/NavSatFix. The fields are used to indicate the latitude, longitude, altitude, status, quality of the service, and the covariance matrix. In our example, we will use the latitude and the longitude to project them to a 2D Cartesian coordinate system named Universal Transverse Mercator (UTM).

Check a message to see a real example of the data sent. You can do it with the following command:

$ rostopic echo /fix

You will see something that looks similar to the following output:

---
header:
seq: 3
stamp:
secs: 1404993925
nsecs: 255094051
frame_id: /gps
status:
status: 0
service: 1
latitude: 28.0800916667
longitude: -15.451595
altitude: 315.3
position_covariance: [3.24, 0.0, 0.0, 0.0, 3.24, 0.0, 0.0, 0.0, 12.96]
position_covariance_type: 1
---

Creating an example project to use GPS

In this example, we are going to project the latitude and the longitude of GPS to a 2D Cartesian space. For this, we will use a function written by Chuck Gantz that converts latitudes and longitudes into UTM coordinates. The node will subscribe to the /fix topic where GPS data is sent. You can find the code in chapter8_tutorials in the c8_fixtoUTM.cpp file:

#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
#include <stdio.h>
#include <iostream>
#include <sensor_msgs/NavSatFix.h>
geometry_msgs::Point global_position;
ros::Publisher position_pub;
void gpsCallBack(const sensor_msgs::NavSatFixConstPtr& gps)
{
  double northing, easting;
  char zone;
  LLtoUTM(gps->latitude, gps->longitude, northing, easting , &zone);
  global_position.x = easting;
  global_position.y = northing;
  global_position.z = gps->altitude;
}
int main(int argc, char** argv){
  ros::init(argc,argv, "fixtoUTM");
  ros::NodeHandle n;
  ros::Subscriber gps_sub = n.subscribe("fix",10, gpsCallBack);
  position_pub = n.advertise<geometry_msgs::Point> ("global_position", 1);
  ros::Rate loop_rate(10);
  while(n.ok())
  {
    ros::spinOnce();
    loop_rate.sleep();
  }
}

First, you should declare the NavSatFix message using #include <sensor_msgs/NavSatFix.h>.

This way, we can subscribe to the /fix topic in the ros::Subscriber gps_sub = n.subscribe("fix",10, gpsCallBack) main function.

All the action happens in the gpsCallBack() function. We will use the LltoUTM() function to make the conversion from latitudes and longitudes to the UTM space. We will publish a geometry_msg/Point topic named /global_position with the UTM northing and easting coordinates and the altitude from the GPS.

To try this code, after running the GPS driver, you can use the following command:

$ rosrun chapter8_tutorials c8_fixtoUTM

You can use GPS data to improve your robot localization using Kalman filters to fuse odometry and IMU with NavSatFix data.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset