pantor / ruckig

Motion Generation for Robots and Machines. Real-time. Jerk-constrained. Time-optimal.
https://ruckig.com
MIT License
634 stars 155 forks source link

ErrorExecutionTimeCalculation in a very specific case #141

Open old-ma opened 1 year ago

old-ma commented 1 year ago

The ruckig.update() will return ErrorExecutionTimeCalculation in the codes below The strange thing is that if I change current_position very little, instead of 0.0049921875, like 0.0049921876 or 0.0049921874, the planning is ok... the version is v0.8.4

 constexpr int DOF{1};
  Ruckig<DOF> ruckig {0.001}; // Number DoFs; control cycle in [s]
  InputParameter<DOF> inp; // Number DoFs
  inp.current_position = {0.0049921875};
  inp.current_velocity = {0};
  inp.current_acceleration = {0};
  inp.target_position = {0.005};
  inp.target_velocity = { 0};
  inp.target_acceleration = { 0};
  inp.max_velocity = { 0.1};
  inp.max_acceleration = { 2.5};
  inp.max_jerk = {2000};

  OutputParameter<DOF> out; // Number DoFs
  auto res = ruckig.update(inp, out);
  std::cout << res << std::endl; // res == ErrorExecutionTimeCalculation
old-ma commented 1 year ago

I debugged the source codes of v0.8.4 The issue is here [ in position-step1.cpp:178]

        if (t < t_min_none || t > t_max_none) {
            continue;
        }

In this specific case, t = 0.0025000000000000005, but t_max_non = 0.0025000000000000001, so it looks like a numeric problem. Thus the correct profile is missed. It might need some epsilon to check FLOAT LARGER THAN logic.

MMaDiWo commented 1 year ago

I have a similar problem with the same error code, i.e. ErrorExecutionTimeCalculation. The update call fails right at the first call with the following inputs.

ruckig::Ruckig<3> otg{0.01};
ruckig::InputParameter<3> input;
ruckig::OutputParameter<3> output;

input.synchronization = Synchronization::Phase;
input.duration_discretization = DurationDiscretization::Discrete;

input.max_velocity = {3, 1, 3};
input.max_acceleration = {3, 2, 1};
input.max_jerk = {4, 3, 2};

input.current_position = {0.1, 0.1, -0.5000000000000001};
input.current_velocity = {0, 0, 0};
input.current_acceleration = {0, 0, 0};

input.target_position = {0, 0, -1};
input.target_velocity = {0, 0, 0};
input.target_acceleration = {0, 0, 0};

If I change the input.current_position[2] value from -0.5000000000000001 to -0.5 the update call succeeds.

fricher commented 1 year ago

Hi everyone,

Having the same issue on 9.2.0 with these parameters:

inp.current_position = {1};
inp.current_velocity = {0};
inp.current_acceleration = {0};
inp.target_position = {0.98};
inp.target_velocity = {0};
inp.target_acceleration = {0};
inp.max_velocity = {1};
inp.max_acceleration = {100};
inp.max_jerk = {10000};
MMaDiWo commented 1 year ago

I found a workaround by effectively truncating some trailing digits.

For each DOF index i do: input.current_position[i] = ((double)((int) (input.current_position[i] * 100000)) / 100000);