Skip to content

Numerical Instabilities in Python Bindings #240

@chpohl

Description

@chpohl

I came across weird/inconsistent behavior when using ruckig for trajectory generation in Python. I tracked down the error and created a minimum example that reproduces the error:

import pytest
from ruckig import InputParameter, Result, Ruckig, Trajectory

start_1 = [0.6900046551907393, 1.867349375974835e-06, 0.6670294289887627, 0]
start_2 = [0.6900046551918803, -1.1288094259602022e-16, 0.6670294289873331, 0.0]

bad_target = [0.6900046551907393, 1.867349375974835e-06, 0.6670294289887627, 0.9999999999999998]
good_target = [0.6900046551918803, -1.1288094259602022e-16, 0.6670294289873331, 1.0000000000000002]


@pytest.fixture
def input_params():
    inp = InputParameter(4)
    inp.max_velocity = [0.25, 0.25, 0.25, 1]
    inp.max_acceleration = [0.5, 0.5, 0.5, 0.5]
    inp.max_jerk = [10, 10, 10, 0.5]
    inp.current_velocity = [0, 0, 0, 0]
    inp.current_acceleration = [0, 0, 0, 0]
    inp.target_velocity = [0, 0, 0, 0]
    inp.target_acceleration = [0, 0, 0, 0]
    return inp


@pytest.fixture
def otg():
    return Ruckig(4)


@pytest.mark.parametrize("start", [start_1, start_2])
@pytest.mark.parametrize("target", [good_target, bad_target])
def test_ruckig(start, target, input_params, otg):
    input_params.current_position = start
    input_params.target_position = target
    trajectory = Trajectory(4)
    result = otg.calculate(input_params, trajectory)
    assert result == Result.Working

The above test succeeds for both runs with the good_target, but fails for both instantiations of the bad_target with a RuckigError:

E       ruckig.RuckigError: 
E       [ruckig] error in step 1, dof: 3 input: 
E       inp.current_position = [0.6900046551907393, 1.867349375974835e-06, 0.6670294289887627, 0]
E       inp.current_velocity = [0, 0, 0, 0]
E       inp.current_acceleration = [0, 0, 0, 0]
E       inp.target_position = [0.6900046551907393, 1.867349375974835e-06, 0.6670294289887627, 0.9999999999999998]
E       inp.target_velocity = [0, 0, 0, 0]
E       inp.target_acceleration = [0, 0, 0, 0]
E       inp.max_velocity = [0.25, 0.25, 0.25, 1]
E       inp.max_acceleration = [0.5, 0.5, 0.5, 0.5]
E       inp.max_jerk = [10, 10, 10, 0.5]

The error message is a bit confusing, because it says dof: 3 , whereas everything is clearly instantiated for 4 dof. I don't see why the behavior between these similar targets should be so different. If it is not a bug, a more helpful error message would be nice. I ran these tests on version 0.15.3 of the ruckig python bindings, but also going back to an older version (i.e. before the switch to nanobind) did not change the error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug-communitySomething isn't working in the community version

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions