ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
5

need help converting lat-long coordinates into meters

asked 2012-12-18 15:26:23 -0600

mte2010 gravatar image

I have a bunch of coordinates captured from my gps in lat-long coordinates, the formatting is like so:

lat: 43.47798167 # Latitude (degrees). Positive is north of equator; negative is south.

long: -80.545065 # Longitude (degrees). Positive is east of prime meridian, negative west.

I'm simply getting this data from my /fix topic, or gps_common/GPSFix.msg. I want to convert all of my lat-long coord's to meters.

For example, this is position 1:

lat: 43.47798167, long: -80.545065

This is position 2:

lat: 43.47784167, long: -80.54544833

What's the distance traveled in meters from position 1 to 2 in the x and y directions?

Thanks.

edit retag flag offensive close merge delete

6 Answers

Sort by ยป oldest newest most voted
1

answered 2012-12-21 04:43:54 -0600

joq gravatar image

The geodesy package provides interfaces to convert between lat/long and UTM coordinates in both C++ and Python. Once points are converted to UTM, you can use normal Euclidean distance calculations in meters.

It uses proj4 for the Python implementation, and handles conversion to and from the standard ROS sensor_msgs/NavSatFix.

edit flag offensive delete link more
3

answered 2017-03-15 16:51:22 -0600

updated 2017-03-20 15:49:02 -0600

Geodesy seems to be the most official way to convert between latitude/logitude and UTM coordinates. As I wasn't able to find any code examples, here are some lines, which worked for me. Start with:

#include <geodesy/utm.h>

For coordinate conversions, you need data of type geographic_msgs::GeoPoint and geodesy::UTMPoint.

Example for Lat/Lon -> UTM conversion:

  geographic_msgs::GeoPoint geo_pt;
  geo_pt.latitude = latitude;
  geo_pt.longitude = longitude;
  geo_pt.altitude = altitude;
  geodesy::UTMPoint utm_pt(geo_pt);

Example for UTM -> Lat/Lon conversion:

  geodesy::UTMPoint utm_pt(easting, northing, altitude, zone, band);
  geographic_msgs::GeoPoint geo_pt;
  geo_pt = geodesy::toMsg(utm_pt);

Don't forget to add geodesy to your CMakeLists.txt:

find_package(catkin REQUIRED COMPONENTS geodesy)
edit flag offensive delete link more
1

answered 2012-12-18 15:36:57 -0600

Thomas D gravatar image

Take a look at libproj, which you can install in Ubuntu using

sudo apt-get install libproj-dev

To get distance traveled in meters you can convert latitude and longitude to UTM coordinates, where UTM coordinates are measured in meters. That conversion is very easy when using libproj. If you want to use latitude and longitude look for great circle equations.

edit flag offensive delete link more

Comments

how do i use this library in ros?

mte2010 gravatar image mte2010  ( 2012-12-20 13:41:10 -0600 )edit

Use find_package(Proj) with this file, then use target_link_library(your_program ${PROJ_LIBRARY}). See here for how to use custom find cmake file.

Thomas D gravatar image Thomas D  ( 2012-12-20 17:02:40 -0600 )edit
1

It's probably easier and more portable to use the geodesy package that @joq links to in his answer instead of writing your own code based on the same libproj library. You should probably mark that as the correct answer.

Thomas D gravatar image Thomas D  ( 2012-12-21 04:57:18 -0600 )edit
1

answered 2016-09-03 12:13:58 -0600

chrisalbertson gravatar image

All of the answers about converting LL to UTM are good but miss one tiny point that might be important. UTM coordinates are only continuous within a zone. If you cross a zone boundary the numbers reset. So a robot that is driving across a living room floor is not likely to cross a UTM zone boundary unless you are very unlucky but a self driving car might cross zone boundaries frequently. Each zone has its has its own coordinate system relative to the SW corner.

For larger distances the great circle is the way to go. It is simple enough that you can learn to estimate distances between two LL points in your head.

The other method, that pretty much simplifies calculations with LL is to convert LL to Cartesian. Define (0, 0, 0) as the center of the Earth.

A Great Circle is made by slicing the Earth in half, exactly in half, with a plane that is defined by three points, the center of the Earth and the pair of LL points in question. Now all your points are on a plane and we can use High School geometry to solve the problem

Define a circle with radius equal to the earth radius and center at the center of the earth (the equator is a good example of a great circle) Lets first assume your two LL points are on the equator. It is trivial to find their angular separation. It is the difference in longitude. What fraction of a circle is this angle? Multiply that fraction by the circumference of the equator. Use rounded values and this is easy to compute in your head.

What happens if the two points are NOT on the equator? Then imagine a new great circle centerd on the earth that passes through these points. It's circumference is the same as the equator (we assume a spherical Earth) Find the angular separation between these to points as viewed from the Earth's center. and continue as above.

How to find the angle? You solve a couple right triangle problems. A long time ago people where able to do this kind of work while on moving sailing ships by candlelight without a calculator. You need to know basic trig but not more

Yes you could simply use a library and that is what I did back when I worked on GIS systems but it is MUCH better if you understand what is going on.

edit flag offensive delete link more
0

answered 2018-10-16 04:24:13 -0600

Vincent R gravatar image

Here is another way to do it : https://github.com/ethz-asl/geodetic_...

edit flag offensive delete link more
0

answered 2014-11-21 08:05:25 -0600

oogabooga gravatar image

I am implementing something similar. You should probably look into http://docs.ros.org/hydro/api/gps_com... I think this is what you are looking for "static void LLtoUTM (const double Lat, const double Long, double &UTMNorthing, double &UTMEasting, std::string &UTMZone)" so just pass parameters and then this will do the rest. :) Hope this helps. :)

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2012-12-18 15:26:23 -0600

Seen: 9,487 times

Last updated: Oct 16 '18