While away from a joystick-enabled system over the weekend, I decided to start hacking at the Nasal/AI integration. What I *really* wanted to make work was carrier landings, which required getting velocity information from the AI models. But this required work on the YASim gear model to understand the moving objects and to calculate per-gear forces. But *this* required an unambiguous transformation between the YASim coordinate system and the terrain one. For historical reasons (I'll get to that in a second) YASim has always used its own WGS84 approximation, which isn't quite identical to the SimGear one.
So basically, I had to get the two datums to agree. This turned out to be, er, interesting. The reason YASim has its own code is that it does its work in a global cartesian frame. Each frame, the coordinates get exported from XYZ to lat/lon/alt, and imported back if anything changes. That transformation *has* to be symmetric. If it's not, the FDM will see the precision error as a space warp and get confused. SimGear has a sgGeodToCart() function, but no sgCartToGeod() equivalent. So I rolled my own; the altitude handling wasn't quite correct, but at least it was symmetric. Since nothing outside of YASim ever saw the funny XYZ coordinates, things worked fine. Until now, when I need to make the funny XYZ coordinates agree with the scenery objects' coordinate system. To make a long story short: I wrote an implementation of sgCartToGeod() that I'm pretty proud of. But I got hung up over some existing bugs in sgGeodToCart() and the related functions, so I rewrote those too. This is obviously the kind of "big change" that shouldn't be checked in without code review, so here's the argument: Problems with the existing LaRC code: + It's slightly wrong. I don't quite know when it happened, but the sg_geodesy files have incorrect numbers for the WGS84 equatorial radius. This number is part of the standard, it *really* shouldn't vary. Asking for, say, the cartesian equivalent of 0 lat, 0 lon, 0 alt gives a vector that is off by about a meter. And frustratingly, I can't fix it; there are some other derived quantities that appear as magic numbers in the code. But the derivations don't match the comments. Simply fixing the radius number breaks the functions in ways I don't understand, because: + It's opaque. Lots of trig functions; lots of greek variable names; no explanatory inline comments; no description of the algorithm. It looks like someone typed the code in out of a book. That's fine, if you get it right. But it makes maintenance really hard. + It's missing sgCartToGeod(), which is a firm requirement for me. You can approximate this with sgGeodToGeoc/sgPolarToCart3D (lots of existing code does), but that isn't symmetric -- running the two functions as a cycle, the numbers come out off by 1-4 meters, which isn't good enough for YASim to use for terrain intersections. Advantages of the new code: + It seems to be correct. At points on the equator and at the poles, it matches the WGS84 standard exactly, where the old code is off by about a meter. In a test with randomly selected points, it matches the old code to within about a meter, which is reasonably strong evidence that I've got it right. + It is, hopefully, easier to understand. There is significantly less actual code in the new implementaiton, and I've tried to explain what I'm doing. I won't say it isn't opaque (this stuff is a little brain-twisty to begin with), but I've honestly tried to make it readable. + It includes sgCartToGeod(). This is the fun part. The implementation is a recursion relation that is symmetric with sgGeodToCart() and accurate all the way down to the precision of a IEEE double (about 6 nanometers for points on the surface). It's not terribly fast (something like 4000 CPU cycles, about 6x slower than my implementation of sgGeodToCart), but is only called a few times per frame in typical usage. A quick inspection turned up several places in the code where the existing API was being used to emulate this function; replacing them with this function made things cleaner and simpler. Anyway, anyone who is interested should grab the update at: http://www.plausible.org/andy/new_geodesy.tar.gz The new code is in sg_geodesy.*, the other files are just minor API fixups (mostly because sg_geodesy.hxx no longer includes polar3d.hxx) It appears to work for me with no change of functionality. I won't bother checking it in until I finish the YASim gear work which requires it. Yell if you think something is wrong. Andy _______________________________________________ Flightgear-devel mailing list [EMAIL PROTECTED] http://mail.flightgear.org/mailman/listinfo/flightgear-devel
