Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert gps coordinates to local reference #29

Open
Liumouliu opened this issue Jun 11, 2021 · 14 comments
Open

convert gps coordinates to local reference #29

Liumouliu opened this issue Jun 11, 2021 · 14 comments

Comments

@Liumouliu
Copy link

Hi,

I want to transform the WGS-84 Geodetic point (lat, lon, h) to the local (X,Y,Z) coordinate, using the provided reference (42.294319, -83.223275).

After the transformation, I think I would get very similar results as pose_raw.csv.

Here is what I have done:

Generally speaking, I first transform the WGS-84 Geodetic point (lat, lon, h) to Earth-Centered Earth-Fixed (ECEF) coordinates (x, y, z). Then, the ECEF coordinates are transformed to East-North-Up coordinates.

However, I have the following questions:

  1. the provided reference (42.294319, -83.223275) does not contain the altitude of the reference, which hinders me to obtain the Z coordinate. Can you please share the altitude of the reference?

  2. the provided reference (42.294319, -83.223275) has six decimals. However, the real-time recorded items in gps.csv have ten decimals. Can you please explain the motivation?

  3. After parsing the file gps.csv, I got slightly different results, compared with items in pose_raw.csv.

For example:

GT: x : -1644.91390701, y : 1335.59171013; My: x : -1645.054286939695, y : 1335.1813690268768; Github: x : -1645.327115755862, y : 1334.9546098449466
GT: x : -1644.87310037, y : 1335.60461139; My: x : -1645.0135018018027, y : 1335.194133655902; Github: x : -1645.2863271411193, y : 1334.9673839304598
GT: x : -1644.75078146, y : 1335.64325695; My: x : -1644.8910969154442, y : 1335.2324164154254; Github: x : -1645.163911817825, y : 1335.0056950780595
GT: x : -1644.70994124, y : 1335.65615531; My: x : -1644.8502787941275, y : 1335.2451810321118; Github: x : -1645.1230902180873, y : 1335.018469162866
GT: x : -1644.66908808, y : 1335.66905943; My: x : -1644.809444182155, y : 1335.2579345378645; Github: x : -1645.0822521232294, y : 1335.0312321408526
GT: x : -1644.62845006, y : 1335.68189438; My: x : -1644.7685930739356, y : 1335.2707102548661; Github: x : -1645.0413975343001, y : 1335.0440173338925
GT: x : -1644.58757031, y : 1335.69479944; My: x : -1644.72773372329, y : 1335.283474862213; Github: x : -1645.0005346978107, y : 1335.0567914186993
GT: x : -1644.54668006, y : 1335.70770073; My: x : -1644.6868578851947, y : 1335.2962394682925; Github: x : -1644.9596553693486, y : 1335.0695655042125
GT: x : -1644.50578347, y : 1335.72059332; My: x : -1644.6459820471835, y : 1335.3090040756938; Github: x : -1644.9187760398372, y : 1335.0823395897257
GT: x : -1644.46509403, y : 1335.73341287; My: x : -1644.605106213379, y : 1335.3217575747874; Github: x : -1644.877896711375, y : 1335.095102566299
GT: x : -1644.42418363, y : 1335.74630271; My: x : -1644.5642138884473, y : 1335.334511072365; Github: x : -1644.8370008877923, y : 1335.1078655442852
GT: x : -1644.38326264, y : 1335.75919394; My: x : -1644.5233133211952, y : 1335.34726456738; Github: x : -1644.7960968187479, y : 1335.1206285208584
GT: x : -1644.34233305, y : 1335.77208839; My: x : -1644.482404510576, y : 1335.3600180637834; Github: x : -1644.7551845031924, y : 1335.1333914988447
GT: x : -1644.30139827, y : 1335.7849923; My: x : -1644.4414874538413, y : 1335.3727826680674; Github: x : -1644.7142639411259, y : 1335.146165584358
GT: x : -1644.26045842, y : 1335.79789444; My: x : -1644.4005621522492, y : 1335.385547271062; Github: x : -1644.6733351314992, y : 1335.1589396691645
GT: x : -1644.21951287, y : 1335.81079218; My: x : -1644.3596368544556, y : 1335.3983007670995; Github: x : -1644.6324063208235, y : 1335.1717026464444
GT: x : -1644.17856419, y : 1335.82368318; My: x : -1644.3187033152187, y : 1335.4110542645226; Github: x : -1644.5914692646857, y : 1335.1844656244307
GT: x : -1644.13779667, y : 1335.83651219; My: x : -1644.2777615337031, y : 1335.4238077616092; Github: x : -1644.550523960988, y : 1335.1972286010039

For each line:

GT denotes the provided items in pose_raw.csv;

My denotes the results of my method;

Github denotes the method from the issue #12
section 7.5 of this document (https://portal.opengeospatial.org/files/16-011r4)

You can see that the results of different methods differ.

Can you please explain the reasons?

I guess the reason may come from the six decimals of the reference.

I attached my code and related files below.

please rename check_gps.txt to check_gps.py
check_gps.txt

pose_raw.csv
gps.csv

Thank you very much!

@Liumouliu
Copy link
Author

Hi,

Again regarding the discrepancy between geodetic coordinates in the file gps.csv and file pose_raw.csv.

For the dataset: 2017-10-26-V2-Log1.

After decoding the rosbag, I obtained files gps.csv and pose_raw.csv.

Using the reference (42.294319, -83.223275), I was able to transform the geodetic coordinates in the file gps.csv to NED coordinates in the file pose_raw.csv.

I was expecting a very small discrepancy between the transformed NED coordinates and coordinates in the file pose_raw.csv.

However, I noticed some gaps. For example:

the first transformed NED coordinates are : [-36.924676304816145, 487.12477939227466]
the first coordinates in the file pose_raw.csv are : [-34.4421893746, 488.117873591 ]

the last transformed NED coordinates are : [-7961.3896358869915, -9905.590429565611]
the last coordinates in the file pose_raw.csv are : [-7897.53911295, -9949.94211612]

Can you please spot the reasons?

I'm sure my transformation script is correct and the obtained results are the same as using the lib https://github.com/geospace-code/pymap3d

Thank you very much!

Best,
liu

@ankitvora7
Copy link
Contributor

ankitvora7 commented Jun 16, 2021

Hi @Liumouliu Regarding your first comment about the small discrepancies in GT, My and Github, I would say that is expected. The reasons could be the projection-reprojection errors, the rounding off errors or even as you pointed out, 6/10 decimal errors. If you can tell me little bit about your application, I could probably suggest which pose information you could use. To answer your questions -

  1. Since we are not really interested in the absolute value of Z, we always treat the altitude as 0 at the origin.
  2. The change in latitude/longitude beyond the 6th decimal is not very large. The Applanix sensor reports 10 decimals but we truncate it to 6 decimals for maps and map origin purposes.

@Liumouliu
Copy link
Author

Thank you very much for your reply.

I also think it could be the projection-reprojection errors.

Can you please tell me which projection method is used by you -- to calculate the NED coordinates.

My application is to achieve lane-level accuracy for camera pose estimation.

@ankitvora7
Copy link
Contributor

Thank you very much for your reply.

I also think it could be the projection-reprojection errors.

Can you please tell me which projection method is used by you -- to calculate the NED coordinates.

My application is to achieve lane-level accuracy for camera pose estimation.

Okay in that case, my recommendation would be to estimate the camera pose information using the pose_raw (subsample that to 1hz such that it simulates a GPS) and then compare it with the pose_ground_truth topic to get localization errors.

@Liumouliu
Copy link
Author

Yeah, your suggestion is doable.

However, I want to make the geodetic coordinates in the file gps.csv align with NED coordinates in the file pose_raw.csv.

The reason why I need to do it is that:

I need to download some other dataset (You will know in the near future) using the geodetic coordinates in the file gps.csv.

If the geodetic coordinates in the file gps.csv are NOT aligned with NED coordinates in the file pose_raw.csv, I could not compare my estimation with NED coordinates in the file pose_ground_truth.csv.

@Liumouliu
Copy link
Author

In summary, I want to figure out why there is a gap between the transformed NED coordinates using the geodetic coordinates in the file gps.csv and the provided NED coordinates in the file pose_raw.csv.

Can you please share the method how you obtain pose_raw.csv from gps.csv?

Thank you

@Liumouliu
Copy link
Author

The method which I use is given in the attached file : check_gps.txt

@ankitvora7
Copy link
Contributor

I will share our projection equation shortly

@Liumouliu
Copy link
Author

Thank you very much!

No problem, I will do the comparison and update you my findings (if have)

@Liumouliu
Copy link
Author

Btw:

  1. the provided reference (42.294319, -83.223275) does not contain the altitude of the reference, which hinders me to obtain the Z coordinate. Can you please share the altitude of the reference?

  2. the provided reference (42.294319, -83.223275) has six decimals. However, the real-time recorded items in gps.csv have ten decimals. Can you please explain the motivation?

@ankitvora7
Copy link
Contributor

  1. Since we are not really interested in the absolute value of Z, we always treat the altitude as 0 at the origin.
  2. The change in latitude/longitude beyond the 6th decimal is not very large. The Applanix sensor reports 10 decimals but we truncate it to 6 decimals for maps and map origin purposes.

@Liumouliu
Copy link
Author

Got it!

@ankitvora7
Copy link
Contributor

ankitvora7 commented Jul 22, 2021

I will share our projection equation shortly

Here's the projection that we use to convert between (lat,lon) and (x,y)

void xy_to_lat_lon (const gps_linearization_t *lin, const double xy_m[2], double ll_deg[2])
{
    double dlat = asin (xy_m[0] / lin->radius_ns); // NED
    ll_deg[0] = to_degrees (dlat) + lin->lat0_deg;
    double dlon = asin (xy_m[1] / lin->radius_ew / cos (to_radians (lin->lat0_deg))); // NED
    ll_deg[1] = to_degrees (dlon) + lin->lon0_deg;
}

void
lat_lon_to_xy (const gps_linearization_t *lin, const double ll_deg[2], double xy[2])
{
    double dlat = to_radians (ll_deg[0] - lin->lat0_deg);
    double dlon = to_radians (ll_deg[1] - lin->lon0_deg);

    // NED
    xy[0] = sin (dlat) * lin->radius_ns;
    xy[1] = sin (dlon) * lin->radius_ew * cos (to_radians (lin->lat0_deg));

}

lin->radius_ns = 6364355.800020
lin->radius_ew = 6387824.938572
lin->lat0_deg = 42.294319
lin->lon0_deg = -83.223275

The to_radians and to_degrees function just converts the input into radians and degrees respectively
ll_deg or xy is the final result that you will use.

@Liumouliu
Copy link
Author

Hi, thank you for the sharing.

Using the provided script, I still notice a gap between transformed GPS and XYZ in the pose_raw.csv or pose_gt.csv.

For example, the first GPS (2017-10-26-V2-Log1)

 lat = 42.2939861865
lon = - 83.2173676888
h = 146.885843327

is transformed to

[-36.968578611726514, 487.16329883448674]

This is different from that in pose_raw.csv or pose_gt.csv

-34.470314091 488.170231485

Can you please double-check it?

Thank you very much!

liu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants