hungpham2511 / toppra

robotic motion planning library
https://hungpham2511.github.io/toppra/index.html
MIT License
603 stars 167 forks source link

Seidel LP 1D: incoherent bounds #244

Open maxpla3 opened 7 months ago

maxpla3 commented 7 months ago

While trying to calculate the trajectory for one joint with setN(1000) I get the following error:

    [WARN]: Seidel LP 1D:
v: -65.9608        0
A:
   -65.9608  -0.0151605
    65.9608 -0.00782363
   0.468679 5.68434e-14
  -0.468679       -1000
          0        -inf
          0        -inf
   -65.9608           0
    65.9608  -0.0229842
-> incoherent bounds. high - low = -1.21284e-13 - 0 = -1.21284e-13
[WARN]: Seidel LP 2D:
v: 1e-09    -1
A:
     -0.002          -1           0
      0.002           1  -0.0229842
    65.9608  0.00710543        -500
   -65.9608 -0.00710543        -500
    65.9608           0        -500
   -65.9608           0        -500
-inf    <= x[0] <= inf
0   <= x[1] <= 0.0229842
-> infeasible

Changing N to other values does not cause that problem. Looks like a numerical problem. The actual solution should probably be 0 here but due do numerical errors the upper bound becomes slightly negative.

maxpla3 commented 7 months ago

The 1D LP in the above post does not have a solution unless one assumes 5.68434e-14 = 0, then the LP becomes solvable with x = 0. I have to figure out where 5.68434e-14 comes from and why it's not exactly 0.

maxpla3 commented 7 months ago

Would this solution make sense?

if upper_bound < lower_bound AND lower_bound - upper_bound < 2 * ABS_TOLERANCE
then
  lower_bound -= ABS_TOLERANCE
  upper_bound += ABS_TOLERANCE

That way, if upper bound is smaller than lower bound due to numerical errors, we'd extend the bounds by a tiny amount and allow a solution between the new bounds?

maxpla3 commented 7 months ago

The issue can be reproduced with following test:

    {
      // Issue #244
      v = { -65.960772491990838, 0.0 };
      A.resize(8, 2);
      A << -65.9607724919908, -0.0151605259038078,
          65.9607724919908, -0.00782362866419491,
          0.468679477393087, 5.6843418860808e-14,
          -0.468679477393087, -1000,
          0, -std::numeric_limits<double>::infinity(),
          0, -std::numeric_limits<double>::infinity(),
          -65.9607724919908, 0,
          65.9607724919908, -0.0229841545680027;

      auto sol = seidel::solve_lp1d(v, A);
      EXPECT_TRUE(sol.feasible);
    }

It fails on EXPECT_TRUE(sol.feasible).