tcx - How to calculate distance between two trackpoints - gps

I'm trying to calculate the distance between points taken from a .tcx file (i.e. with latitude and longitude) when the attribute DistanceMeters is not present. In doing this I used as a test some .tcx with that attribute and I cannot obtain the same distance. I'm aware of the Haversine function (it overshoots in the found implementations btw), I'm aware of distance between GeoJSON (it overshoots using , again). Other tips and suggestions are welcome!
These are 3 points that I used as a benchmark (redacted with only the useful bits).
<Trackpoint>
<Time>2020-11-05T17:26:33.000Z</Time>
<Position>
<LatitudeDegrees>45.809465954080224</LatitudeDegrees>
<LongitudeDegrees>9.09074085764587</LongitudeDegrees>
</Position>
<AltitudeMeters>220.1999969482422</AltitudeMeters>
<DistanceMeters>0.0</DistanceMeters>
</Trackpoint>
<Trackpoint>
<Time>2020-11-05T17:26:35.000Z</Time>
<Position>
<LatitudeDegrees>45.80945455469191</LatitudeDegrees>
<LongitudeDegrees>9.090738091617823</LongitudeDegrees>
</Position>
<AltitudeMeters>220.1999969482422</AltitudeMeters>
<DistanceMeters>0.019999999552965164</DistanceMeters>
</Trackpoint>
<Trackpoint>
<Time>2020-11-05T17:26:40.000Z</Time>
<Position>
<LatitudeDegrees>45.80951012670994</LatitudeDegrees>
<LongitudeDegrees>9.090708252042532</LongitudeDegrees>
</Position>
<AltitudeMeters>220.0</AltitudeMeters>
<DistanceMeters>6.46999979019165</DistanceMeters>
</Trackpoint>

Related

Inconsistent pose pairs in HAND-EYE calibration in HALCON warnings

I am trying to perform hand-eye calibration using HALCON for the UR5 cobot. I am using 'hand_eye_stationarycam_calibration.hdev.But every time , I get a warning that says: 'Inconsistent pose pairenter image description here
Can anybody help me in this issue? I have tried all of the pose types as well, but the warning and fault results remain.
Try looking at the line of code:
check_hand_eye_calibration_input_poses (CalibDataID, 0.001, 0.005, Warnings)
There is a rotation tolerance (0.001 here) and a translation tolerance (0.005 here). Try to increase these values and see if that gets rid of the error.
Sometimes when I've had this problem in the past it was because my units were not consistent. For example, the translation units of the robot pose were all in 'mm' but my camera units were in 'm'. Double check the translation units and ensure they match.
Also I believe the UR5 robot might default to an axis-angle representation. You must ensure your camera poses and robot poses are all in the same format. See the link below for a description from Universal and how to convert between the different formats. You could either use the script from universal to convert to a roll, pitch, yaw convention or you could take the axis angle representation and convert it inside Halcon.
Here is an example of how I converted from axis-angle to 'abg' pose type in Halcon. In this case the camera returned 7 values: 3 describing a translation in X, Y, Z and 4 values describing the rotation using the angle axis convention. This is then converted to a pose type where the first rotation is performed around the Z axis followed by the new Y axis followed by the new X axis (which matched the robot I was using). The other common pose type in Halcon is 'gba' and you might need that one. In general I believe there are 12 different rotation combinations that are possible so you should verify which one is being used for both the camera and the robot.
In general I try and avoid using the terms roll, pitch, and yaw since I've seen it cause confusion in the past. If the translation units are given in X, Y, Z I prefer the rotation be given in Rx, Ry, and Rz followed by the order of rotation.
*Pose of Object Relative to Camera
get_framegrabber_param (NxLib, '/Execute/halcon1/Result/Patterns/PatternPose/Rotation/Angle', RotationAngle)
get_framegrabber_param (NxLib, '/Execute/halcon1/Result/Patterns/PatternPose/Rotation/Axis/\\0', Axis0)
get_framegrabber_param (NxLib, '/Execute/halcon1/Result/Patterns/PatternPose/Rotation/Axis/\\1', Axis1)
get_framegrabber_param (NxLib, '/Execute/halcon1/Result/Patterns/PatternPose/Rotation/Axis/\\2', Axis2)
get_framegrabber_param (NxLib, '/Execute/halcon1/Result/Patterns/PatternPose/Translation/\\0', Txcam)
get_framegrabber_param (NxLib, '/Execute/halcon1/Result/Patterns/PatternPose/Translation/\\1', Tycam)
get_framegrabber_param (NxLib, '/Execute/halcon1/Result/Patterns/PatternPose/Translation/\\2', Tzcam)
axis_angle_to_quat(Axis0, Axis1, Axis2, RotationAngle, QuatObjRelCam)
quat_to_hom_mat3d(QuatObjRelCam, MatObjRelCam)
MatObjRelCam[3] := Txcam/1000
MatObjRelCam[7] := Tycam/1000
MatObjRelCam[11] := Tzcam/1000
hom_mat3d_to_pose(MatObjRelCam, PoseObjRelCam)
convert_pose_type (PoseObjRelCam, 'Rp+T', 'abg', 'point', PoseObjRelCam)
EXPLANATION ON ROBOT ORIENTATION from Universal Robotics

lat_ts on Plate Carree in cartopy

I have data with this spatial reference in proj4 format:
+proj=eqc +lat_ts=8 +lat_0=0 +lon_0=180 +x_0=0 +y_0=0 +a=1737400 +b=1737400 +units=m +no_def
As I understand it, +proj=eqc is the Plate Carree (equidistant cylindrical) as described here.
However, that doesn't take a lat_ts parameter (latitude at true scale). Can anyone explain why, and how I can express this coordinate system in cartopy?
You can't currently express that parameter for Equidistant Cyclindrical in Cartopy. The PlateCarree projection in CartoPy has some weird behavior as well. If this is important to you, I'd suggest opening an issue, or better yet, contributing a Pull Request to add Equidistant Cylindrical as a proper projection to CartoPy.

using gdalwarp to transform from wgs84 to EPSG:3857 does not cover world

i am using gdal 1.10 and 2.1.1.
i have a VRT datasource in WGS84 where i forced the corner coordinates to the min/max values of EPSG:3857 (-180,85.5,180,-85.5).
gdalinfo output for this VRT looks like this:
Size is 1296001, 601200
Coordinate System is:
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,
AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0],
UNIT["degree",0.0174532925199433],
AUTHORITY["EPSG","4326"]]
Origin = (-180.000000000000000,85.500000000000000)
Pixel Size = (0.000277777563443,-0.000284431137725)
Corner Coordinates:
Upper Left (-180.0000000, 85.5000000) (180d 0' 0.00"W, 85d30' 0.00"N)
Lower Left (-180.0000000, -85.5000000) (180d 0' 0.00"W, 85d30' 0.00"S)
Upper Right ( 180.0000000, 85.5000000) (180d 0' 0.00"E, 85d30' 0.00"N)
Lower Right ( 180.0000000, -85.5000000) (180d 0' 0.00"E, 85d30' 0.00"S)
Center ( 0.0000000, -0.0000000) ( 0d 0' 0.01"E, 0d 0' 0.00"S)
Band 1 Block=128x128 Type=Int16, ColorInterp=Gray
Basically, i have the world minus the poles.
Now i want to convert this to EPSG:3857.
I use gdalwarp for this, using bilinear interpolation:
./gdalwarp -of VRT -co TILED=YES -srcnodata 9999 -t_srs 'EPSG:3785' -multi wgs84.vrt wmerc.vrt -overwrite -r bilinear
running gdalinfo on wmerc then gives this:
Size is 995026, 1025175
Coordinate System is:
PROJCS["Popular Visualisation CRS / Mercator (deprecated)",
GEOGCS["Popular Visualisation CRS",
DATUM["Popular_Visualisation_Datum",
SPHEROID["Popular Visualisation Sphere",6378137,0,
AUTHORITY["EPSG","7059"]],
TOWGS84[0,0,0,0,0,0,0],
AUTHORITY["EPSG","6055"]],
PRIMEM["Greenwich",0,
AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,
AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4055"]],
PROJECTION["Mercator_1SP"],
PARAMETER["central_meridian",0],
PARAMETER["scale_factor",1],
PARAMETER["false_easting",0],
PARAMETER["false_northing",0],
UNIT["metre",1,
AUTHORITY["EPSG","9001"]],
AXIS["X",EAST],
AXIS["Y",NORTH],
EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=#null +wktext +no_defs"],
AUTHORITY["EPSG","3785"]]
Origin = (-20037508.342789247632027,20644642.363762538880110)
Pixel Size = (40.275313937642778,-40.275354414328227)
Corner Coordinates:
Upper Left (-20037508.343,20644642.364) (180d 0' 0.00"E, 85d28'11.27"N)
Lower Left (-20037508.343,-20644644.098) (180d 0' 0.00"E, 85d28'11.28"S)
Upper Right (20037476.183,20644642.364) (179d59'58.96"E, 85d28'11.27"N)
Lower Right (20037476.183,-20644644.098) (179d59'58.96"E, 85d28'11.28"S)
Center ( -16.0797308, -0.8670919) ( 0d 0' 0.52"W, 0d 0' 0.03"S)
Band 1 Block=512x128 Type=Int16, ColorInterp=Gray
NoData Value=9999
Note that the corner coordinates for upper/lower left look correct, but the corner coordinates for upper/lower right (the longitude) is missing is missing 32 units.
Broadly put, i am missing a sliver on the right side, but only in regards to the coordinates. The data is there, but the coordinates to the right seem wrong.
Why is that?
i could just modify the coordinates to match the world (longitudinal) using gdal_translate but i fear i am overlooking something else here which might just come back to bite me.
EPSG 3857 bounds latitudes to be between -85 and 80 degrees. It does this for two reasons:
It allows the entire earth to be square and be indexed by a quadtree where every node is a square.
The Mercator projection blows up at the poles; considering that most people who use maps aren't interested in them anyways, the projection kills two birds with one stone and discards them.

Why does SQL Server GEOGRAPHY allow longitudes between -15069° and +15069°? Why ±15069°?

I am using the Microsoft.SqlServer.Types DLL in my projects for validating Latitudes and Longitudes.
The Library validates longitude values between -15069 and 15069 degrees instead from -180 to 180.
Can anybody explain what is the significance or reason that Microsoft is checking the longitude values to be between -15069 and 15069 degrees?
Microsoft has listed the standards for Geo Spatial standards on this website which mentions the Longitude values MUST be between -15069 and 15069 degrees, inclusive.
https://msdn.microsoft.com/en-us/library/ee301753(v=sql.105).aspx
Your inputs in understanding this concept will be appreciated!
Why is longitude not restricted to [-180°..+180°]?
Here's a brief thought experiment.
Which of the following three lines does LINESTRING (-180 0, 180 0) represent?
A line going around the whole globe along the equator in an eastward direction.
A line going around the whole globe along the equator in a westward direction.
A line of length 0, since -180° latitude denotes the same meridian as +180° latitude.
As soon as you decide on any of the three possibilities, you will find that you have no way of modelling the other two cases as LINESTRING (try it!)… at least not when you restrict longitude to the (geographically correct) interval [-180°..+180°]!
Let's see what happens when we relax that restriction:
The line going around the globe in an eastward direction can now be modelled as LINESTRING (-180 0, 180 0). (This seems to match our expectations, since increasing degrees of longitude means "going eastward".)
The line going around the globe in a westward direction now becomes LINESTRING (-180 0, -540 0). (Decreasing degrees of longitude denotes "going westward".)
The line of length 0 becomes LINESTRING (-180 0, -180 0). (No change in coordinates means "no distance travelled".)
Yes, but why did they chose exactly ±15069 degrees?
That, I cannot say. It might have to do with floating-point precision (i.e. spatial computations becoming too imprecise if you specified a point that's "wrapped around" the globe more than 15,069° ÷ 360° = 41,8583… times) or simply a arbitrary limit (i.e. they thought noone will need to be able to construct a spiral that goes around the globe more than approx. 42 times).
Why was latitude restricted to [-90°..+90°], if longitude wasn't restricted?
Let's repeat the above thought experiment: What does LINESTRING (0 90, 0 -90) mean?
A line going around half the globe along the prime meridian in a southward direction.
A line going around half the globe along the prime meridian in a northward direction.
A line of length 0.
We can rule out (3), since POINT (0 90) and POINT (0 -90) are distinct points: namely, the north pole and the south pole. A line going from one to the other definitely does not have zero length.
We can also rule out (2), simply because it does not make any sense to say "going northward" when starting at the north pole. You can only stay there, or go south, which is already covered by (1).
So we end up unambiguously with (1). The reason, therefore, why latitude was restricted to the geographically meaningful [-90°..+90°] is because there is never any ambiguity when modelling lines that touch or cross the geographic poles. This is because there are no sudden degree "jumps" like there are with longitude (where one and the same meridian is described both by -180° and +180°).

Finding coordinates between longitude and latitude

How to find a few coordinates that are in the straight line, between 2 coordinates?
For example:
Start coordinate: Lat=X1 Long=Y1
End coordinate: Lat=X2 Long=Y2
Make a straight line from X1,Y1 to X2,Y2.
Then find 5 points that are located in that line, that are spread in the same distance.
Anyone can help to find the algorithm and calculation?
The coordinate is in decimal format, e.g. 50.123456, 6.123456
Thanks.
There are no "straight lines" on a sphere (or ellipsoid).
Anyway, you'll need to:
Calculate the distance and initial azimuth from (x1,y1) to (x2,y2).
You can use Vincenty's inverse method.
Calculate the coordinate of points with distance (0,25d, 0.5d, 0.75d) from (x1,y1) at that azimuth (plus points (x1,y1) and (x2,y2) of course).
You can use Vincenty's direct method.
Both direct and inverse methods are described on Wikipedia.
An extremely accurate implementations for both direct and inverse problems are available as part of GeographicLib.
Less accurate, but much simpler methods are described in Aviation Formulary.