davideberly / GeometricTools

A collection of source code for computing in the fields of mathematics, geometry, graphics, image analysis and physics.
Boost Software License 1.0
1.08k stars 202 forks source link

There seems to be something wrong with the results of Line3 and circle3's nearest distance algorithms #84

Closed Ethan-CYM closed 5 months ago

Ethan-CYM commented 5 months ago

Sorry to bother you, but I'm having some issues using GeometricTools

I have normalized the direction vectors of the line and the circle.

I noticed that when the normal of the circle is in some special direction, such as {1,0,0}, {0,1,0}, the result is correct, but the normal of the circle is in some other direction, the result is wrong. In some directions, output.distance is a large number, such as 5e+16, in other directions, the result is 0.

If the problem is coming from my code, I hope you can point it out, and if the problem is coming from GeometricTools, can you solve it?

Here is my code:

gtl::Vector<double, 3> direction = {1,1,0}; gtl::Normalize(direction);

gtl::Line3 line({1,1,-0}, direction); gtl::Normalize(line.direction);

gtl::Circle3 circle({-1,2,-0}, direction, 10); gtl::Normalize(circle.normal);

gtl::DCPQuery<double, gtl::Line3, gtl::Circle3> distLC;

auto LCOutput = distLC(line, circle);

cout << "LCOutput.distance: " << LCOutput.distance << std::endl;

Ethan-CYM commented 5 months ago

If use the following code, the program will exit abnormally auto LCOutput = distLC.Robust(line, circle);

davideberly commented 5 months ago

Using Microsoft Visual Studio 2022 on a Windows 11 machine, I set up a temporary directory structure with root folder GeometricTools, subfolder GTL with all its contents from github, and I added a subfolder to GTL named TestCymBugReport and containing a MSVS 2022 project. The project has a single file with a 'main' program, and the include path is "../../.". The single file contains

#include <GTL/Mathematics/Distance/3D/DistLine3Circle3.h>

int main()
{
    gtl::Vector<double, 3> direction = { 1.0, 1.0, 0.0 };
    gtl::Normalize(direction);
    gtl::Line3<double> line({ 1.0, 1.0, -0.0 }, direction);
    gtl::Normalize(line.direction);
    gtl::Circle3<double> circle({ -1.0, 2.0, -0.0 }, direction, 10.0);
    gtl::Normalize(circle.normal);
    gtl::DCPQuery<double, gtl::Line3<double>, gtl::Circle3<double>> distLC{};
    auto LCOutput = distLC(line, circle);
    // numClosestPairs = 1
    // lineClosest[0] = (0.5, 0.5, 0.0)
    // lineClosest[1] = (0.0, 0.0, 0.0)  // not used because numClosestPairs is 1
    // circleClosest[0] = (6.0710678118654755, -5.0710678118654755, 0.0)
    // circleClosest[1] = (0.0, 0.0, 0.0)  // not used because numClosestPairs is 1
    // distance = 7.8786796564403581
    // sqrDistance = 62.073593128807154
    // equidistant = false
    LCOutput = distLC.Robust(line, circle);
    // Same output as the previous call.
}

Both queries return the same results. Using Mathematica, I verified that these are correct. The Robust call did not exit abnormally.

Do you have more context to provide so I can reproduce the errors you mention? Thank you.

Ethan-CYM commented 5 months ago

I found this problem to be related to my development environment. My project was developed in ubuntu18.04 and based on ROS Melodic(Robot Operating System).

When building the .cpp file that contains GeometricTools code, if the ROS library is included in the cmakelists file and linked to the target file, the calculation results will be abnormal. If ROS library is not linked when building the peoject, the result is correct.

I guess this is because GeometricTools has a function with the same name as ROS, and GeometricTools incorrectly calls the ROS function when the project runs.

My solution was to encapsulate the GeometricTools associated code as a static link library and link it to my project.

I appreciate your prompt reply, which has helped me find the cause of the problem. I think this is not a GeometricTools error. But if you would like to explore the issue more deeply, I would be happy to provide you with more evidence and codes to ensure that you can reproduce this phenomenon.

davideberly commented 5 months ago

The Geometric Tools GTL distribution does not have a function named ROS. Perhaps the problem is the name of another function in GTL? Do you have any type of build output or other information I can read in order to determine what this ROS problem is? For example, if you have a dump of the symbol information, I might be able to find the conflict. If ROS is something I can download, and if you have a small project for which the problem occurs, I can compile on my Ubuntu machine in hopes of diagnosing the issue. Thank you.

Ethan-CYM commented 5 months ago

The project was built without any warnings or information related to the problem. I've built a little project for you to recreate this problem. But you still need to install some dependency libraries

  1. Install ROS melodic

It's worth taking a look at what ros does:

https://www.ros.org/

ROS melodic installation tutorial:

https://wiki.ros.org/melodic/Installation/Ubuntu

Environment configuration tutorial:

https://wiki.ros.org/ROS/Tutorials/InstallingandConfiguringROSEnvironment

  1. A Ros-based robot development kit, epfl-lasa/iiwa_ros, found in my testing that if GeometricTools were built with this package and dependent on ros, the GeometricTools calculations would fail.

https://github.com/epfl-lasa/iiwa_ros

Refer to the links below for instructions to install SpaceVecAlg, RBDyn, mc_rbdyn_urdf, corrade, robot_controllers. But you don't have to clone epfl-lasa/iiwa_ros locally, I will provide it to you, I made some cuts for you.

  1. My project link, please follow my guidance to repeat the problem.

https://github.com/CymGitHub/test_gtl_ros

  1. My guess: epfl-lasa/iiwa_ros needs to use some libraries of ros, but GeometricTools conflicts with the naming of some functions in these libraries. In the Rlease version, the compiler incorrectly links these functions with the same name, causing the function calculation results in GeometricTools to be incorrect. In the debug version, the calculation results of GeometricTools are always correct. In addition, if you include GeometricTools and do not rely on ros at all, the calculation results will also be correct. Or delete epfl-lasa/iiwa_ros from the project. Some functions in the ros library will not be compiled, wrong links will not occur, and the calculation results will be correct. But when these three conditions are combined, an error occurs. If you're confused, go back to step 3 and follow my instructions to run the code.

For a more nuanced guess, there are a lot of vector and matrix calculations in robot applications. I guess some of the vector computations have naming conflicts, such as Normalize (), Cross (), etc. This is just my guess. I hope it helps.

davideberly commented 5 months ago

I was able to get ROS installed and cloned your test_gtl_ros repository. The catkin_make command fails. Many of your cmake files have /home/cym/* paths. I tried changing these to use my home path, but more failed attempts at compiling. Complaints about /home//test/src not existing.

davideberly commented 5 months ago

By the way, my GTL code uses the namespace 'gtl'. It is unclear why same-named functions would be the problem. The C++ decorated names should be different between GTL functions and functions from other packages that ROS uses. For example, ROS uses Eigen, but Eigen has its own namespaces that do not appear to be in conflict with my namespace name 'gtl'. If anything, I would expect the compiler to complain if there were name conflicts.

Also note that the GTL header files are of the form: #include <GTL/SomePath/SomeFile.h>. The design of my include paths is supposed to protect against same-named files.

davideberly commented 5 months ago

CymGitHub, feel free to re-open if you provide CMake files that allow me to reproduce what you are seeing. Thank you.