-
Notifications
You must be signed in to change notification settings - Fork 0
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
Feat/cv orchestrator localize, (GSD Implementation with Unit Tests) #158
Changes from 5 commits
1fc14bf
cefec89
9d17ab4
c52e5ca
e38a741
9465722
40a22d5
7e58721
c123253
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
[submodule "protos"] | ||
path = protos | ||
url = git@github.com:tritonuas/protos.git | ||
url = https://github.com/tritonuas/protos.git |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,7 @@ ECEFLocalization::ECEFCoordinates ECEFLocalization::ENUtoECEF(ENUCoordinates off | |
// Converts ECEF coordinates to GPS coordinates using Heikkinen's procedure | ||
GPSCoord ECEFLocalization::ECEFtoGPS(ECEFCoordinates ecef) { | ||
GPSCoord gps; | ||
double a = 6378137; | ||
double a = EARTH_RADIUS_METERS; | ||
double b = 6356752; | ||
double e2 = 1 - ((b*b)/(a*a)); | ||
double ep2 = ((a*a)/(b*b)) - 1; | ||
|
@@ -106,6 +106,97 @@ GPSCoord ECEFLocalization::localize(const ImageTelemetry& telemetry, const Bbox& | |
return targetCoord; | ||
} | ||
|
||
|
||
GPSCoord GSDLocalization::localize(const ImageTelemetry& telemetry, const Bbox& targetBbox) { | ||
return GPSCoord(); | ||
} | ||
GPSCoord gps; | ||
|
||
// Ground Sample Distance (mm/pixel), 1.0~2.5cm per px is ideal aka 10mm~25mm ppx | ||
double GSD = (SENSOR_WIDTH * (telemetry.altitude)) / (FOCAL_LENGTH_MM * IMG_WIDTH_PX); | ||
|
||
// Midpoints of the image | ||
double img_mid_x = IMG_WIDTH_PX / 2; | ||
double img_mid_y = IMG_HEIGHT_PX / 2; | ||
|
||
//midpoints of bounding box around the target | ||
double target_x = (targetBbox.x1 + targetBbox.x2)/2; | ||
double target_y = (targetBbox.y1 + targetBbox.y2)/2; | ||
|
||
// calculations of bearing | ||
// L = (distance(middle, bbox))*GSD | ||
double length = (sqrt(pow((target_x - img_mid_x), 2) + pow((target_y - img_mid_y), 2) * GSD)); | ||
|
||
//Translate Image Cordinates to Camera Cordinate Frame (Origin to Center of Image instead of Top Left) | ||
double target_camera_cord_x = target_x - (IMG_WIDTH_PX / 2); | ||
double target_camera_cord_y = (IMG_HEIGHT_PX / 2) - target_y; | ||
|
||
//Angle of Bearing (Angle from north to target) | ||
double thetaB = telemetry.heading + atan(target_camera_cord_x / target_camera_cord_y); | ||
|
||
//Translate bearing to the 3 quadrant if applicable | ||
if (target_camera_cord_x < 0 && target_camera_cord_y < 0){ | ||
thetaB = 180.0 + thetaB; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fantastic comments on this function. They really make it a lot easier to parse what's going on. |
||
|
||
//Finds the offset of the bbox | ||
double calc_cam_offset_x = target_camera_cord_x * GSD * 0.001; //mm to M | ||
double calc_cam_offset_y = target_camera_cord_y * GSD * 0.001; //mm to M | ||
|
||
//Calculates the cordinates using the offset | ||
GPSCoord calc_coord = CalcOffset((calc_cam_offset_x), (calc_cam_offset_y), (telemetry.latitude), (telemetry.longitude)); | ||
|
||
return calc_coord; | ||
} | ||
|
||
/* | ||
Takes the in two cordinaates and outputs their distance in meters. | ||
|
||
Parameters: | ||
- lat1/lon1 (First Cordinate) | ||
- lat2/lon2 (Second Cordinate) | ||
|
||
@returns distance in meters | ||
|
||
Reference: http://www.movable-type.co.uk/scripts/latlong.html | ||
*/ | ||
|
||
double GSDLocalization::distanceInMetersBetweenCords(const double lat1, const double lon1, const double lat2, const double lon2){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really like the inclusion of this function for reasoning about accuracy in terms of feet/meters instead of latitude/longitude. |
||
double e1 = lat1 * M_PI / 180; | ||
double e2 = lat2 * M_PI / 180; | ||
|
||
double d1 = (lat2 - lat1) * M_PI / 180; | ||
double d2 = (lon2 - lon1) * M_PI / 180; | ||
|
||
double a = sin(d1/2) * sin(d1/2) + cos(e1) * cos(e2) * sin(d2/2) * sin(d2/2); | ||
|
||
double c = 2 * atan2(sqrt(a), sqrt(1-a)); | ||
|
||
double d = EARTH_RADIUS_M * c; | ||
|
||
return d; | ||
} | ||
|
||
/* | ||
Takes the position of the camera in blender and the position of the generated target in meters | ||
|
||
Parameters: | ||
-image_offset_x/y - meters from center of plane (0,0) | ||
-cam_lat/lon - Set cordinates of plane | ||
|
||
@returns true (mostly) world cordinate of target | ||
*/ | ||
|
||
GPSCoord GSDLocalization::CalcOffset(const double offset_x, const double offset_y, const double lat, const double lon) { | ||
double dLat = offset_y / EARTH_RADIUS_M; | ||
double dLon = offset_x / (EARTH_RADIUS_M * cos(M_PI * lat / 180)); | ||
|
||
double latO = lat + dLat * 180/M_PI; | ||
double lonO = lon + dLon * 180/M_PI; | ||
|
||
GPSCoord output; | ||
|
||
output.set_latitude(latO); | ||
output.set_longitude(lonO); | ||
|
||
return output; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: I wouldn't hate a more descriptive name instead of
CalcOffset
but it's not that big of a deal.