2012-03-12 2 views
0

EDIT: это неинициализированный переменное ... :(несовместимый выход фиксируется путем размещения отладочного

Объяснение: Конструктор PointLLA я использовал только прошел через широту и долготы, но я никогда не явно установить внутренний элемент высоты переменная до 0. Ошибка новичков ...

Оригинальный вопрос: У меня довольно жуткое время с ошибкой в ​​моем коде. Я вычисляю расстояния между одной точкой и углами прямоугольника. случай, точка центрирована по прямоугольнику, поэтому я должен получить четыре равных расстояния. Я получаю три равных расстояния, а одно почти равное значение расстояния - это несоответствие палатка (разная при каждом ее запуске).

Если у меня есть несколько ключевых операторов отладки (в основном это просто вызов std :: cout), которые явно распечатывают местоположение каждого прямоугольника, я получаю ожидаемое значение расстояния и несогласованность исчезает. Вот соответствующий код:

// 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; 

Так что, если я бегу показано выше код, я получить выход следующим образом:

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 

Точно так, как ожидалось. Обратите внимание, что все значения distTo * совпадают. Я могу запускать программу снова и снова, и получаю точно такой же результат. Но теперь, если я закомментировать блок, который я отметил в приведенном выше коде, я получаю что-то вроде этого:

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

Каждый пробег будет немного отличаться distToNW. Почему distToNW, а не другие значения? Я не знаю. Еще несколько прогонов:

463.06218 
462.79352 
462.76194 
462.74772 
463.09787 
464.04648 

Итак ... что здесь происходит? Я попробовал очистить/перестроить свой проект, чтобы увидеть, произошло ли что-то странное, но это не помогло. Я использую GCC 4.6.3 с целью x86.

EDIT: добавление определений соответствующих функций.

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)); 
    } 
+0

Просто ужасно. Мне жаль вас. –

+0

Вы пытались выборочно удалить инструкции отладки? Выйдя в функцию 'DistanceTo', чтобы узнать, что пошло не так? –

+1

Обеспечьте реализацию «convLLAToECEF» и «DistanceTo» –

ответ

5

Противоречивая выход предполагает, что либо вы делаете использование неинициализированной переменной где-то в коде, или у Вас есть ошибка памяти (доступ к памяти, который был удален, двойное удаление памяти и т.д.). Я не вижу ни одной из этих вещей в коде, который вы вставили, но есть много другого кода, который вызывается.

Создает ли конструктор Vec3 все переменные-члены в ноль (или какое-то известное состояние)? Если нет, тогда сделайте это и посмотрите, поможет ли это. Если они уже инициализированы, посмотрите более подробно на convLLAToECEF и PointLLA, чтобы узнать, не инициализируются ли какие-либо переменные или имеются ли там какие-либо ошибки памяти.

+0

Да, это была неинициализированная переменная. Не могу поверить, что я пропустил это ... большое вам спасибо. Я потратил впустую, четыре часа на это: / – Prismatic

0

Мне кажется, что функция DistanceTo прослушивается в некотором роде. Если вы не можете решить, что происходит, немного экспериментируйте и отчитайтесь.

  • Попробуйте переупорядочить выходы, чтобы убедиться, что это все еще NW.
  • Попробуйте повторить пункт NW 2-3 раза в разные вары, чтобы убедиться, что они даже согласованы за один проход.
  • Попробуйте использовать другой camEye для каждой точки, чтобы исключить из-за состояния в этом классе.
0

Насколько я ненавижу, вы прошли через него в отладчике? Я обычно склоняюсь к отладке на основе stdout, но похоже, что это поможет. В стороне, у вас есть побочные эффекты от чего-то неприятного ногами.

Я предполагаю, что тот факт, что вы ожидаете (по праву, конечно) все четыре значения должны быть одинаковыми, маскирует «NW/SW/NE/SE» где-то где-то. Первое, что я хотел бы сделать, это выделить блок, который у вас есть, в его собственную функцию (которая принимает поле и координаты точки), а затем запустить ее с точкой в ​​нескольких разных местах. Я думаю, что ошибка должна, вероятно, быстро разобраться в этом вопросе.

0

Посмотрите, если проблема воспроизводится, если у вас есть там отладочные инструкции, но переместите их после вывода. Тогда операторы отладки могут помочь определить, был ли поврежден объект Vec3 или его расчет.

Другие идеи: введите код под valgrind.

Пор над выводом продукции.

Смежные вопросы