简体   繁体   English

通过调试语句放置修复了不一致的输出

[英]inconsistent output fixed by debug statement placement

EDIT: it was an uninitialized variable... :( 编辑:这是一个未初始化的变量... :(

Explanation: The PointLLA constructor I used only passed through Latitude and Longitude, but I never explicitly set the internal Altitude member variable to 0. Rookie mistake... 说明:我使用的PointLLA构造函数仅通过纬度和经度传递,但是我从未将内部Altitude成员变量显式设置为0。菜鸟错误...

Original Question: I'm having a pretty horrible time with a bug in my code. 原始问题:我的代码中有一个错误,现在真是太恐怖了。 I'm calculating distances between a single point and the corners of a rectangle. 我正在计算单个点和矩形角之间的距离。 In this case, the point is centered over the rectangle so I should get four equal distances. 在这种情况下,该点在矩形上方居中,因此我应该获得四个相等的距离。 I get three equal distances, and one almost equal distance value that's inconsistent (different every time it runs). 我得到三个相等的距离,以及一个几乎相等的距离值,该值不一致(每次运行时都不同)。

If I have a few key debug statements (pretty much just a std::cout call) that explicitly print out the location of each rectangle corner, I get the expected value for the distance and the inconsistency disappears. 如果我有一些关键的调试语句(几乎只是一个std :: cout调用),可以显式打印出每个矩形角的位置,则可以得到距离的期望值,并且不一致现象消失了。 Here's the relevant code: 以下是相关代码:

// calculate the minimum and maximum distance to
// camEye within the available lat/lon bounds
Vec3 viewBoundsNE;   convLLAToECEF(PointLLA(maxLat,maxLon),viewBoundsNE);
Vec3 viewBoundsNW;   convLLAToECEF(PointLLA(maxLat,minLon),viewBoundsNW);
Vec3 viewBoundsSW;   convLLAToECEF(PointLLA(minLat,minLon),viewBoundsSW);
Vec3 viewBoundsSE;   convLLAToECEF(PointLLA(minLat,maxLon),viewBoundsSE);

// begin comment this block out, and buggy output
OSRDEBUG << "INFO: NE (" << viewBoundsNE.x
         << "  " << viewBoundsNE.y
         << "  " << viewBoundsNE.z << ")";
OSRDEBUG << "INFO: NW (" << viewBoundsNW.x
         << "  " << viewBoundsNW.y
         << "  " << viewBoundsNW.z << ")";
OSRDEBUG << "INFO: SE (" << viewBoundsSW.x
         << "  " << viewBoundsSW.y
         << "  " << viewBoundsSW.z << ")";
OSRDEBUG << "INFO: SW (" << viewBoundsSE.x
         << "  " << viewBoundsSE.y
         << "  " << viewBoundsSE.z << ")";
// --------------- end

// to get the maximum distance, find the maxima
// of the distances to each corner of the bounding box
double distToNE = camEye.DistanceTo(viewBoundsNE);
double distToNW = camEye.DistanceTo(viewBoundsNW); // <-- inconsistent
double distToSE = camEye.DistanceTo(viewBoundsSE);
double distToSW = camEye.DistanceTo(viewBoundsSW);

std::cout << "INFO: distToNE: " << distToNE << std::endl;
std::cout << "INFO: distToNW: " << distToNW << std::endl; // <-- inconsistent
std::cout << "INFO: distToSE: " << distToSE << std::endl;
std::cout << "INFO: distToSW: " << distToSW << std::endl;

double maxDistToViewBounds = distToNE;

if(distToNW > maxDistToViewBounds)
{   maxDistToViewBounds = distToNW;   }

if(distToSE > maxDistToViewBounds)
{   maxDistToViewBounds = distToSE;   }

if(distToSW > maxDistToViewBounds)
{   maxDistToViewBounds = distToSW;   }

OSRDEBUG << "INFO: maxDistToViewBounds: " << maxDistToViewBounds;

So if I run the code shown above, I'll get output as follows: 因此,如果运行上面显示的代码,我将得到如下输出:

INFO: NE (6378137  104.12492  78.289415)
INFO: NW (6378137  -104.12492  78.289415)
INFO: SE (6378137  -104.12492  -78.289415)
INFO: SW (6378137  104.12492  -78.289415)
INFO: distToNE: 462.71851
INFO: distToNW: 462.71851
INFO: distToSE: 462.71851
INFO: distToSW: 462.71851
INFO: maxDistToViewBounds: 462.71851

Exactly as expected. 完全符合预期。 Note that all the distTo* values are the same. 请注意,所有distTo *值都相同。 I can run the program over and over again and I'll get exactly the same output. 我可以一遍又一遍地运行该程序,我将得到完全相同的输出。 But now, if I comment out the block that I noted in the code above, I get something like this: 但是现在,如果我注释掉上面代码中提到的代码块,则会得到以下信息:

INFO: distToNE: 462.71851
INFO: distToNW: 463.85601
INFO: distToSE: 462.71851
INFO: distToSW: 462.71851
INFO: maxDistToViewBounds: 463.85601

Every run will slightly vary distToNW. 每次运行distToNW都会略有不同。 Why distToNW and not the other values? 为什么选择distToNW而不选择其他值? I don't know. 我不知道。 A few more runs: 更多运行:

463.06218
462.79352
462.76194
462.74772
463.09787
464.04648

So... what's going on here? 所以...这是怎么回事? I tried cleaning/rebuilding my project to see if there was something strange going on but it didn't help. 我尝试清理/重建项目,以查看是否发生了奇怪的事情,但这没有帮助。 I'm using GCC 4.6.3 with an x86 target. 我正在使用带有x86目标的GCC 4.6.3。

EDIT: Adding the definitions of relevant functions. 编辑:添加相关功能的定义。

void MapRenderer::convLLAToECEF(const PointLLA &pointLLA, Vec3 &pointECEF)
{
    // conversion formula from...
    // hxxp://www.microem.ru/pages/u_blox/tech/dataconvert/GPS.G1-X-00006.pdf

    // remember to convert deg->rad
    double sinLat = sin(pointLLA.lat * K_PI/180.0f);
    double sinLon = sin(pointLLA.lon * K_PI/180.0f);
    double cosLat = cos(pointLLA.lat * K_PI/180.0f);
    double cosLon = cos(pointLLA.lon * K_PI/180.0f);

    // v = radius of curvature (meters)
    double v = ELL_SEMI_MAJOR / (sqrt(1-(ELL_ECC_EXP2*sinLat*sinLat)));
    pointECEF.x = (v + pointLLA.alt) * cosLat * cosLon;
    pointECEF.y = (v + pointLLA.alt) * cosLat * sinLon;
    pointECEF.z = ((1-ELL_ECC_EXP2)*v + pointLLA.alt)*sinLat;
}

    // and from the Vec3 class defn
    inline double DistanceTo(Vec3 const &otherVec) const
    {
        return sqrt((x-otherVec.x)*(x-otherVec.x) +
                    (y-otherVec.y)*(y-otherVec.y) +
                    (z-otherVec.z)*(z-otherVec.z));
    }

The inconsistent output suggests that either you're making use of an uninitialized variable somewhere in your code, or you have some memory error (accessing memory that's been deleted, double-deleting memory, etc). 不一致的输出表明您正在代码中的某个地方使用未初始化的变量,或者您遇到了一些内存错误(访问已删除的内存,重复删除内存等)。 I don't see either of those things happening in the code you pasted, but there's lots of other code that gets called. 我看不到您粘贴的代码中发生的任何事情,但是还有许多其他代码被调用。

Does the Vec3 constructor initialize all member variables to zero (or some known state)? Vec3构造函数是否将所有成员变量初始化为零(或某个已知状态)? If not, then do so and see if that helps. 如果没有,那么这样做,看看是否有帮助。 If they're already initialized, take a closer look at convLLAToECEF and PointLLA to see if any variables are not getting initialized or if you have any memory errors there. 如果它们已经初始化,请仔细查看convLLAToECEF和PointLLA,以查看是否未初始化任何变量或那里是否存在任何内存错误。

Seems to me like the DistanceTo function is bugged in some way. 在我看来, DistanceTo函数在某种程度上存在错误。 If you cannot work out what is up, experiment a bit, and report back. 如果您无法解决问题,请尝试一下并报告。

  • Try reordering the outputs to see if it's still NW that is wrong. 尝试重新排序输出,以查看是否仍然是NW错误。
  • Try redoing the NW point 2-3 times into different vars to see if they are even consistent in one run. 尝试将NW点重做2-3次到不同的变量中,以查看一次运行是否一致。
  • Try using a different camEye for each point to rule out statefulness in that class. 尝试为每个点使用不同的camEye以排除该类中的有状态性。

As much as I hate it, have you stepped through it in a debugger? 我讨厌它,您是否在调试器中逐步完成了它? I usually bias towards stdout based debugging, but it seems like it'd help. 我通常偏向基于stdout的调试,但似乎很有帮助。 That aside, you've got side effects from something nasty kicking around. 除此之外,您还会因讨厌的事情而产生副作用。

My guess is that the fact that you expect (rightfully of course) all four values to be the same is masking a "NW/SW/NE/SE" typo someplace. 我的猜测是,您期望(当然理所当然)所有四个值都相同的事实在某种程度上掩盖了“ NW / SW / NE / SE”错字。 First thing I'd do is isolate the block you've got here into it's own function (that takes the box and point coordinates) then run it with the point in several different locations. 我要做的第一件事是将您在此处获得的块隔离到它自己的函数中(该函数具有框和点坐标),然后在几个不同的位置使用该点运行它。 I think the error should likely expose itself quickly at that point. 我认为该错误很可能会很快暴露出来。

See if the problem reproduces if you have the debug statements there, but move them after the output. 看看问题是否重现,如果您在其中有调试语句,但是将其移到输出之后。 Then the debug statements could help determine whether it was the Vec3 object that was corrupted, or the calculation from it. 然后,调试语句可以帮助确定是损坏的Vec3对象还是根据Vec3对象进行的计算。

Other ideas: run the code under valgrind . 其他想法:在valgrind下运行代码。

Pore over the disassembly output. 在拆卸输出上打孔。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM