pantor / ruckig

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

Error in Calculation Time? #152

Closed chinahuangyong closed 1 year ago

chinahuangyong commented 1 year ago

@pantor

#include <iostream>
#include <fstream>

#include <ruckig/ruckig.hpp>

using namespace ruckig;

int main() {
    std::fstream traj;

    std::time_t time_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    std::string time_now_str = asctime(gmtime(&time_now));
    std::string file_name = "./traj_" + time_now_str + ".csv";

    traj.open(file_name, std::ios::out);
    if (!traj.is_open()) {
        std::cout << "traj open failed" << std::endl;
    }

    // Create instances: the Ruckig OTG as well as input and output parameters
    Ruckig<2> otg {0.001};  // control cycle
    InputParameter<2> input;
    OutputParameter<2> output;

    // Set input parameters
    input.current_position = {0, 0};
    input.current_velocity = {0, 0};
    input.current_acceleration = {0, 0};

    input.target_position = {10, 10};
    input.target_velocity = {0, 0};
    input.target_acceleration = {0, 0};

    input.max_velocity = {100, 100};
    input.max_acceleration = {100, 100};
    input.max_jerk = {30, 30};

    input.synchronization = ruckig::Synchronization::Time;

    // Generate the trajectory within the control loop
//    std::cout << "t | p1 | p2 | p3" << std::endl;
    while (otg.update(input, output) == Result::Working) {
        auto& p = output.new_position;
//        std::cout << output.time << " " << p[0] << " " << p[1] << " " << p[2] << " " << std::endl;

        traj << output.time << "," << output.new_position[0] << "," << output.new_velocity[0] << ","
        << output.new_acceleration[0] << std::endl;
        output.pass_to_input(input);
    }

    std::cout << "output time1: " << output.time << std::endl;
    std::cout << "output profiles size: " << output.trajectory.get_profiles().size() << std::endl;
    std::cout << "output profiles time: " << output.trajectory.get_profiles().at(0).at(0).t_sum.back() << std::endl;

    for(int i=0; i<7; i++) {
        std::cout << "output profiles1 t" << i << ": " << output.trajectory.get_profiles().at(0).at(0).t.at(i) << std::endl;
    }

    for(int i=0; i<7; i++) {
        std::cout << "output profiles t_sum" << i << ": " << output.trajectory.get_profiles().at(0).at(0).t_sum.at(i) << std::endl;
    }

    for(int i=0; i<8; i++) {
        std::cout << "output profiles a" << i << ": " << output.trajectory.get_profiles().at(0).at(0).a.at(i) << std::endl;
    }

    for(int i=0; i<7; i++) {
        std::cout << "output profiles j" << i << ": " << output.trajectory.get_profiles().at(0).at(0).j.at(i) << std::endl;
    }

    for(int i=0; i<2; i++) {
        for(int j=0; j<7; j++) {
            std::cout << "joint" << i << ": "<< "output trajectory t" << j << ": " << output.trajectory.get_profiles().at(0).at(i).t.at(j) << std::endl;
        }
    }

    std::cout << "trajectory duration: " << output.trajectory.get_duration() << " [s]." << std::endl;
    std::cout << "trajectory run time: " << output.calculation_duration << std::endl;

    traj.close();
}

joint0: output trajectory t0: 0.550321
joint0: output trajectory t1: 0
joint0: output trajectory t2: 1.10064
joint0: output trajectory t3: 0
joint0: output trajectory t4: 0
joint0: output trajectory t5: 0
joint0: output trajectory t6: 0.550321

Screenshot from 2023-02-08 14-02-39

it should be t2 equal t4, and t2 should be 0.550321~0.550322.

pantor commented 1 year ago

This seems to be fine to me. Why should t2 be equal to t4? It would be ambiguous anyway, as the resulting trajectory would be identical (as t3==0). I know that the paper states this, but the Ruckig library has evolved since then 😉

chinahuangyong commented 1 year ago

1676169111006

From the curve, it is true that t3=0, but a2, a3, a4, a5 should also be equal to 0,but here a2 is not equal zero.

1676169273712

pantor commented 1 year ago

Why should a2 be zero? Or, why should t2 == t4?

Ruckig doesn't make any guarantees about the internal data structure of the profiles, and the resulting trajectories are correct and identical. The current data structure has advantages in computational efficiency, so there are some reasons to use a2 != 0.

chinahuangyong commented 1 year ago

27503db1638d8e217288d36b276258b

like this, if t2 is jerk(-1), and then is t6, this means t3 t4 t5 are all equal 0.

pantor commented 1 year ago

Yes, and what's the problem with t3, t4, t5 being all zero? I currently don't see a bug or issue here.

I think the point is: The trajectories are all identical, and there isn't a unique timing for t1-t7. Ruckig doesn't give any guarantees about the internal timings t1-t7.

chinahuangyong commented 1 year ago

Ruckig doesn't give any guarantees about the internal timings t1-t7, if so, i do not have any problem.

pantor commented 1 year ago

Great, thanks for the clarification!