pantor / ruckig

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

High variances in calculation time #156

Closed CesMak closed 1 year ago

CesMak commented 1 year ago

Hey there, I just checked variances regarding calculation time using the cpp implemenation. Here is what I get for calculating a simple 1DoF trajectory: Calculation mean 31.7 [us]. max: 517 [us] min: 7.1 [us]

1) Is there anything I am doing wrong? 2) Is there a speed-up algorithm available if you have very simple requirements (1Dof, 0 start, 0 end acc and vel?)

Code:

#include <iostream>
#include <numeric>
#include <ruckig/ruckig.hpp>

using namespace ruckig;

int main() {
    // Generate the trajectory within the control loop
    //std::cout << "t | p1" << std::endl;
    std::vector<double> result = {};
    InputParameter<1> input;
    OutputParameter<1> output;
    for (int i = 0; i < 1000; i++)
    {
      // Create instances: the Ruckig OTG as well as input and output parameters
      Ruckig<1> otg{0.001};  // control cycle in seconds
      // Set input parameters
      input.current_position = {0.0};
      input.current_velocity = {0.0};
      input.current_acceleration = {0.0};

      input.target_position = {5.0};
      input.target_velocity = {0.0};
      input.target_acceleration = {0.0};

      input.max_velocity = {3.0};
      input.max_acceleration = {3.0};
      input.max_jerk = {4.0};
      double calculation_duration{0.0};
      while (otg.update(input, output) == Result::Working)
      {
        auto& p = output.new_position;
        //std::cout << output.time << " " << p[0] << " " << std::endl;

        output.pass_to_input(input);
        if (output.new_calculation)
        {
          calculation_duration = output.calculation_duration;
        }
      }
      result.push_back(calculation_duration);
    }
    double sum = std::accumulate(result.begin(), result.end(), 0.0);
    double mean = sum / result.size();

    double max = *std::max_element(result.begin(), result.end());
    double min = *std::min_element(result.begin(), result.end());

    std::cout << "Trajectory duration: " << output.trajectory.get_duration() << " [s]." << std::endl;
    std::cout << "Calculation mean " << mean << " [us]." <<" max: "<<max<<" [us]"<<" min: "<<min<<" [us]" << std::endl;
}
pantor commented 1 year ago

Hi CesMak,

can you give me some more information on the OS, compiler, and CPU?

First, the calculation seems to be very slow. Are you running on embedded hardware? Are you compiling with optimization on?

Second, when measuring the variance in the range of microseconds, please make sure that the OS is not interrupting the benchmark. Are you running on a real-time OS and prioritized the benchmark correctly?

From looking at the code, you're doing everything the right way, and Ruckig already has a fast-pass for specific cases such as zero start and target velocity.

pantor commented 1 year ago

In case it's still relevant, feel free to reopen the issue.