Skip to content

Commit 956f648

Browse files
committed
Updated gps utility functions
1 parent 4b51857 commit 956f648

File tree

1 file changed

+34
-30
lines changed

1 file changed

+34
-30
lines changed

math/gps_util.h

+34-30
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ struct GPSPoint {
3636
double time;
3737
double lat;
3838
double lon;
39-
double heading; // True North
39+
double heading; // True North (degrees)
4040
};
4141

4242
struct GPSTranslator {
43+
GPSTranslator() : is_origin_set(false) {}
44+
4345
string GetMapFileFromName(const string& maps_dir, const string& map) {
4446
return maps_dir + "/" + map + "/" + map + ".gpsmap.txt";
4547
}
@@ -54,16 +56,19 @@ struct GPSTranslator {
5456
}
5557
printf("Map origin: %12.8lf, %12.8lf\n", gps_origin_latitude,
5658
gps_origin_longitude);
59+
is_origin_set = true;
5760
return true;
5861
}
5962

6063
void SetOrigin(double latitude, double longitude, double orientation) {
6164
gps_origin_latitude = latitude;
6265
gps_origin_longitude = longitude;
6366
map_orientation = orientation;
67+
is_origin_set = true;
6468
}
6569

6670
Vector2d GPSToMetric(const double latitude, const double longitude) {
71+
CHECK(is_origin_set);
6772
const double theta = DegToRad(latitude);
6873
const double c = std::cos(theta);
6974
const double s = std::sin(theta);
@@ -78,6 +83,7 @@ struct GPSTranslator {
7883
}
7984

8085
void MetricToGPS(const Vector2d& loc, double* longitude, double* latitude) {
86+
CHECK(is_origin_set);
8187
const double theta = DegToRad(gps_origin_latitude);
8288
const double c = std::cos(theta);
8389
const double s = std::sin(theta);
@@ -93,6 +99,7 @@ struct GPSTranslator {
9399
double gps_origin_longitude;
94100
double gps_origin_latitude;
95101
double map_orientation;
102+
bool is_origin_set;
96103

97104
// Earth geoid parameters from WGS 84 system
98105
// https://en.wikipedia.org/wiki/World_Geodetic_System#A_new_World_Geodetic_System:_WGS_84
@@ -155,7 +162,9 @@ inline std::tuple<double, double, int> gpsToUTM(double lat, double lon) {
155162
return std::make_tuple(easting, northing, zone);
156163
}
157164

158-
inline double gpsDistance(double lat0, double lon0, double lat1, double lon1) {
165+
inline double gpsDistance(const GPSPoint& p0, const GPSPoint& p1) {
166+
const auto& [lat0, lon0] = std::make_tuple(p0.lat, p0.lon);
167+
const auto& [lat1, lon1] = std::make_tuple(p1.lat, p1.lon);
159168
// Convert latitude and longitude to radians
160169
double lat0_rad = lat0 * M_PI / 180.0;
161170
double lon0_rad = lon0 * M_PI / 180.0;
@@ -171,53 +180,48 @@ inline double gpsDistance(double lat0, double lon0, double lat1, double lon1) {
171180
return 6371000 * c; // Radius of Earth in meters
172181
}
173182

174-
inline std::tuple<double, double> gpsToGlobalCoord(double lat0, double lon0,
175-
double lat1, double lon1) {
183+
inline Eigen::Vector2d gpsToGlobalCoord(const GPSPoint& p0,
184+
const GPSPoint& p1) {
185+
const auto& [lat0, lon0] = std::make_tuple(p0.lat, p0.lon);
186+
const auto& [lat1, lon1] = std::make_tuple(p1.lat, p1.lon);
187+
176188
// Convert latitude and longitude to utm coordinates
177189
const auto& [e0, n0, zone0] = gpsToUTM(lat0, lon0);
178190
const auto& [e1, n1, zone1] = gpsToUTM(lat1, lon1);
179-
return {e1 - e0, n1 - n0};
180-
}
181191

182-
inline Eigen::Affine2f gpsToLocal(double current_lat, double current_lon,
183-
double current_heading, double goal_lat,
184-
double goal_lon, double goal_heading) {
185-
// Step 1: Convert current and goal GPS coordinates to UTM
186-
const auto& [curr_easting, curr_northing, curr_zone] =
187-
gpsToUTM(current_lat, current_lon);
188-
const auto& [goal_easting, goal_northing, goal_zone] =
189-
gpsToUTM(goal_lat, goal_lon);
190-
// Ensure that both coordinates are in the same UTM zone
191-
if (goal_zone != curr_zone) {
192+
if (zone0 != zone1) {
192193
throw std::runtime_error("GPS points are in different UTM zones.");
193194
}
194195

195-
// Step 2: Calculate the translation vector from the current position to the
196-
// goal in UTM
197-
double dx = goal_easting - curr_easting;
198-
double dy = goal_northing - curr_northing;
196+
return {e1 - e0, n1 - n0}; // x y
197+
}
198+
199+
inline Eigen::Affine2f gpsToLocal(const GPSPoint& current,
200+
const GPSPoint& goal) {
201+
// Step 1: Convert the GPS coordinates to global coordinates
202+
const auto& dvec = gpsToGlobalCoord(current, goal);
199203

200-
// Step 3: Convert the current heading to radians and adjust for x-axis
204+
// Step 2: Convert the current heading to radians and adjust for x-axis
201205
// reference Since 0 degrees points along the y-axis and rotates
202206
// counter-clockwise, convert to radians with 0 degrees aligned along the
203207
// x-axis
204-
double current_heading_rad = (90.0 - current_heading) * M_PI / 180.0;
208+
double current_heading_rad = (90.0 - current.heading) * M_PI / 180.0;
205209

206-
// Step 4: Rotate the translation vector to the robot's local frame
207-
double local_x =
208-
dx * cos(-current_heading_rad) - dy * sin(-current_heading_rad);
209-
double local_y =
210-
dx * sin(-current_heading_rad) + dy * cos(-current_heading_rad);
210+
// Step 3: Rotate the translation vector to the robot's local frame
211+
double local_x = dvec.x() * cos(-current_heading_rad) -
212+
dvec.y() * sin(-current_heading_rad);
213+
double local_y = dvec.x() * sin(-current_heading_rad) +
214+
dvec.y() * cos(-current_heading_rad);
211215

212-
// Step 5: Convert the goal heading to the local frame
213-
double goal_heading_rad = (90.0 - goal_heading) * M_PI / 180.0;
216+
// Step 4: Convert the goal heading to the local frame
217+
double goal_heading_rad = (90.0 - goal.heading) * M_PI / 180.0;
214218
double local_heading = goal_heading_rad - current_heading_rad;
215219

216220
// Normalize local heading to the range [-pi, pi]
217221
while (local_heading > M_PI) local_heading -= 2 * M_PI;
218222
while (local_heading < -M_PI) local_heading += 2 * M_PI;
219223

220-
// Step 6: Create the affine transformation for the local pose of the goal
224+
// Step 5: Create the affine transformation for the local pose of the goal
221225
Eigen::Affine2f transform = Eigen::Translation2f(local_x, local_y) *
222226
Eigen::Rotation2Df(local_heading);
223227

0 commit comments

Comments
 (0)