Package Summary
Tags | No category tags. |
Version | 0.14.0 |
License | MIT |
Build type | CMAKE |
Use | RECOMMENDED |
Repository Summary
Checkout URI | https://github.com/pantor/ruckig.git |
VCS Type | git |
VCS Version | main |
Last Updated | 2024-12-08 |
Dev Status | DEVELOPED |
CI status | No Continuous Integration |
Released | RELEASED |
Tags | No category tags. |
Contributing |
Help Wanted (0)
Good First Issues (0) Pull Requests to Review (0) |
Package Description
Additional Links
Maintainers
- Lars Berscheid
Authors
- Lars Berscheid
Ruckig
Instantaneous Motion Generation for Robots and Machines.
Ruckig generates trajectories on-the-fly, allowing robots and machines to react instantaneously to sensor input. Ruckig calculates a trajectory to a target waypoint (with position, velocity, and acceleration) starting from any initial state limited by velocity, acceleration, and jerk constraints. Besides the target state, Ruckig allows to define intermediate positions for waypoint following. For state-to-state motions, Ruckig guarantees a time-optimal solution. With intermediate waypoints, Ruckig calculates the path and its time parametrization jointly, resulting in significantly faster trajectories compared to traditional methods.
More information can be found at ruckig.com and in the corresponding paper Jerk-limited Real-time Trajectory Generation with Arbitrary Target States, accepted for the Robotics: Science and Systems (RSS), 2021 conference.
Installation
Ruckig has no dependencies (except for testing). To build Ruckig using CMake, just run
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
To install Ruckig in a system-wide directory, you can either use (sudo) make install
or install it as debian package using cpack by running
cpack
sudo dpkg -i ruckig*.deb
An example of using Ruckig in your CMake project is given by examples/CMakeLists.txt
. However, you can also include Ruckig as a directory within your project and call add_subdirectory(ruckig)
in your parent CMakeLists.txt
.
Ruckig is also available as a Python module, in particular for development or debugging purposes. The Ruckig Community Version can be installed from PyPI via
pip install ruckig
When using CMake, the Python module can be built using the BUILD_PYTHON_MODULE
flag. If you’re only interested in the Python module (and not in the C++ library), you can build and install Ruckig via pip install .
.
Tutorial
Furthermore, we will explain the basics to get started with online generated trajectories within your application. There is also a collection of examples that guide you through the most important features of Ruckig. A time-optimal trajectory for a single degree of freedom is shown in the figure below. We also added plots of the resulting trajectories for all examples. Let’s get started!
Waypoint-based Trajectory Generation
Ruckig provides three main interface classes: the Ruckig, the InputParameter, and the OutputParameter class.
First, you’ll need to create a Ruckig instance with the number of DoFs as a template parameter, and the control cycle (e.g. in seconds) in the constructor.
Ruckig<6> ruckig {0.001}; // Number DoFs; control cycle in [s]
The input type has 3 blocks of data: the current state, the target state and the corresponding kinematic limits.
InputParameter<6> input; // Number DoFs
input.current_position = {0.2, ...};
input.current_velocity = {0.1, ...};
input.current_acceleration = {0.1, ...};
input.target_position = {0.5, ...};
input.target_velocity = {-0.1, ...};
input.target_acceleration = {0.2, ...};
input.max_velocity = {0.4, ...};
input.max_acceleration = {1.0, ...};
input.max_jerk = {4.0, ...};
OutputParameter<6> output; // Number DoFs
If you only want to have a acceleration-constrained trajectory, you can also omit the max_jerk
as well as the current
and target_acceleration
value. Given all input and output resources, we can iterate over the trajectory at each discrete time step. For most applications, this loop must run within a real-time thread and controls the actual hardware.
while (ruckig.update(input, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
output.pass_to_input(input); // Don't forget this!
}
Within the control loop, you need to update the current state of the input parameter according to the calculated trajectory. Therefore, the pass_to_input
method copies the new kinematic state of the output to the current kinematic state of the input parameter. If (in the next step) the current state is not the expected, pre-calculated trajectory, Ruckig will calculate a new trajectory based on the novel input. When the trajectory has reached the target state, the update
function will return Result::Finished
.
Intermediate Waypoints
The Ruckig Community Version now supports intermediate waypoints via a cloud API. To allocate the necessary memory for a variable number of waypoints beforehand, we need to pass the maximum number of waypoints to Ruckig via
Ruckig<6> otg {0.001, 8};
InputParameter<6> input {8};
OutputParameter<6> output {8};
The InputParameter
class takes the number of waypoints as an optional input, however usually you will fill in the values (and therefore reserve its memory) yourself. Then you’re ready to set intermediate via points by
input.intermediate_positions = {
{0.2, ...},
{0.8, ...},
};
As soon as at least one intermediate positions is given, the Ruckig Community Version switches to the mentioned (of course, non real-time capable) cloud API. If you require real-time calculation on your own hardware, please contact us for the Ruckig Pro Version.
When using intermediate positions, both the underlying motion planning problem as well as its calculation changes significantly. In particular, there are some fundamental limitations for jerk-limited online trajectory generation regarding the usage of waypoints. Please find more information about these limitations here, and in general we recommend to use
input.intermediate_positions = otg.filter_intermediate_positions(input.intermediate_positions, {0.1, ...});
to filter waypoints according to a (high) threshold distance. Setting interrupt_calculation_duration makes sure to be real-time capable by refining the solution in the next control invocation. Note that this is a soft interruption of the calculation. Currently, no minimum or discrete durations are supported when using intermediate positions.
Input Parameter
To go into more detail, the InputParameter type has following members:
using Vector = std::array<double, DOFs>; // By default
Vector current_position;
Vector current_velocity; // Initialized to zero
Vector current_acceleration; // Initialized to zero
std::vector<Vector> intermediate_positions; // (only in Pro Version)
Vector target_position;
Vector target_velocity; // Initialized to zero
Vector target_acceleration; // Initialized to zero
Vector max_velocity;
Vector max_acceleration;
Vector max_jerk; // Initialized to infinity
std::optional<Vector> min_velocity; // If not given, the negative maximum velocity will be used.
std::optional<Vector> min_acceleration; // If not given, the negative maximum acceleration will be used.
std::optional<Vector> min_position; // (only in Pro Version)
std::optional<Vector> max_position; // (only in Pro Version)
std::array<bool, DOFs> enabled; // Initialized to true
std::optional<double> minimum_duration;
std::optional<double> interrupt_calculation_duration; // [µs], (only in Pro Version)
ControlInterface control_interface; // The default position interface controls the full kinematic state.
Synchronization synchronization; // Synchronization behavior of multiple DoFs
DurationDiscretization duration_discretization; // Whether the duration should be a discrete multiple of the control cycle (off by default)
std::optional<Vector<ControlInterface>> per_dof_control_interface; // Sets the control interface for each DoF individually, overwrites global control_interface
std::optional<Vector<Synchronization>> per_dof_synchronization; // Sets the synchronization for each DoF individually, overwrites global synchronization
On top of the current state, target state, and constraints, Ruckig allows for a few more advanced settings:
- A minimum velocity and acceleration can be specified - these should be a negative number. If they are not given, the negative maximum velocity or acceleration will be used (similar to the jerk limit). For example, this might be useful in human robot collaboration settings with a different velocity limit towards a human. Or, when switching between different moving coordinate frames like picking from a conveyer belt.
- You can overwrite the global kinematic limits to specify limits for each section between two waypoints separately by using e.g.
per_section_max_velocity
. - If a DoF is not enabled, it will be ignored in the calculation. Ruckig will output a trajectory with constant acceleration for those DoFs.
- A minimum duration can be optionally given. Note that Ruckig can not guarantee an exact, but only a minimum duration of the trajectory.
- The control interface (position or velocity control) can be switched easily. For example, a stop trajectory or visual servoing can be easily implemented with the velocity interface.
- Different synchronization behaviors (i.a. phase, time, or no synchonization) are implemented. Phase synchronization results in straight-line motions.
- The trajectory duration might be constrained to a multiple of the control cycle. This way, the exact state can be reached at a control loop execution.
We refer to the API documentation of the enumerations within the ruckig
namespace for all available options.
Input Validation
To check that Ruckig is able to generate a trajectory before the actual calculation step,
ruckig.validate_input(input, check_current_state_within_limits=false, check_target_state_within_limits=true);
// returns true or throws
throws an error with a detailed reason if an input is not valid. You can also set the default template parameter to false via ruckig.validate_input<false>(...)
to just return a boolean true or false. The two boolean arguments check that the current or target state are within the limits. The check includes a typical catch of jerk-limited trajectory generation: When the current state is at maximal velocity, any positive acceleration will inevitable lead to a velocity violation at a future timestep. In general, this condition is fulfilled when
Abs(acceleration) <= Sqrt(2 * max_jerk * (max_velocity - Abs(velocity))).
If both arguments are set to true, the calculated trajectory is guaranteed to be within the kinematic limits throughout its duration. Also, note that there are range constraints of the input due to numerical reasons, see below for more details.
Result Type
The update
function of the Ruckig class returns a Result type that indicates the current state of the algorithm. This can either be working, finished if the trajectory has finished, or an error type if something went wrong during calculation. The result type can be compared as a standard integer.
State | Error Code |
---|---|
Working | 0 |
Finished | 1 |
Error | -1 |
ErrorInvalidInput | -100 |
ErrorTrajectoryDuration | -101 |
ErrorPositionalLimits | -102 |
ErrorExecutionTimeCalculation | -110 |
ErrorSynchronizationCalculation | -111 |
Output Parameter
The output class includes the new kinematic state and the overall trajectory.
Vector new_position;
Vector new_velocity;
Vector new_acceleration;
Trajectory trajectory; // The current trajectory
double time; // The current, auto-incremented time. Reset to 0 at a new calculation.
size_t new_section; // Index of the section between two (possibly filtered) intermediate positions.
bool did_section_change; // Was a new section reached in the last cycle?
bool new_calculation; // Whether a new calculation was performed in the last cycle
bool was_calculation_interrupted; // Was the trajectory calculation interrupted? (only in Pro Version)
double calculation_duration; // Duration of the calculation in the last cycle [µs]
Moreover, the trajectory class has a range of useful parameters and methods.
double duration; // Duration of the trajectory
std::array<double, DOFs> independent_min_durations; // Time-optimal profile for each independent DoF
<...> at_time(double time); // Get the kinematic state of the trajectory at a given time
<...> get_position_extrema(); // Returns information about the position extrema and their times
Again, we refer to the API documentation for the exact signatures.
Offline Calculation
Ruckig also supports an offline approach for calculating a trajectory:
result = ruckig.calculate(input, trajectory);
When only using this method, the Ruckig
constructor does not need a control cycle (delta_time
) as an argument. However if given, Ruckig supports stepping through the trajectory with
while (ruckig.update(trajectory, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
}
starting from the current output.time
(currently Ruckig Pro only).
Tracking Interface
When following an arbitrary signal with position, velocity, acceleration, and jerk-limitation, the straight forward way would be to pass the current state to Ruckig’s target state. However, as the resulting trajectory will take time to catch up, this approach will always lag behind the signal. The tracking interface solves this problem by predicting ahead (e.g. with constant acceleration by default) and is therefore able to follow signals very closely in a time-optimal way. This might be very helpful for (general) tracking, robot servoing, or trajectory post-processing applications.
To use the tracking interface, construct
Trackig<1> otg {0.01}; // control cycle
and set the current state as well as the kinematic constraints via
input.current_position = {0.0};
input.current_velocity = {0.0};
input.current_acceleration = {0.0};
input.max_velocity = {0.8};
input.max_acceleration = {2.0};
input.max_jerk = {5.0};
Then, we can track a signal in an online manner within the real-time control loop
for (double t = 0; t < 10.0; t += otg.delta_time) {
auto target_state = signal(t); // signal returns position, velocity, and acceleration
auto res = otg.update(target_state, input, output);
// Make use of the smooth target motion here (e.g. output.new_position)
output.pass_to_input(input);
}
Please find a complete example here. This functionality can also be used in an offline manner, e.g. when the entire signal is known beforehand. Here, we call the
smooth_trajectory = otg.calculate_trajectory(target_states, input);
method with the trajectory given as a std::vector
of target states. The Tracking interface is available in the Ruckig Pro version.
Dynamic Number of Degrees of Freedom
So far, we have told Ruckig the number of DoFs as a template parameter. If you don’t know the number of DoFs at compile-time, you can set the template parameter to ruckig::DynamicDOFs
and pass the DoFs to the constructor:
Ruckig<DynamicDOFs> otg {6, 0.001};
InputParameter<DynamicDOFs> input {6};
OutputParameter<DynamicDOFs> output {6};
This switches the default Vector from the std::array
to the dynamic std::vector
type. However, we recommend to keep the template parameter when possible: First, it has a performance benefit of a few percent. Second, it is convenient for real-time programming due to its easier handling of memory allocations. When using dynamic degrees of freedom, make sure to allocate the memory of all vectors beforehand.
Custom Vector Types
Ruckig supports custom vector types to make interfacing with your code even easier and more flexible. Most importantly, you can switch to Eigen Vectors simply by including Eigen (3.4 or later) before Ruckig
#include <Eigen/Core> // Version 3.4 or later
#include <ruckig/ruckig.hpp>
and then call the constructors with the ruckig::EigenVector
parameter.
Ruckig<6, EigenVector> otg {0.001};
InputParameter<6, EigenVector> input;
OutputParameter<6, EigenVector> output;
Now every in- and output of Ruckig’s API (such as current_position
, new_position
or max_jerk
) are Eigen types! To define completely custom vector types, you can pass a C++ template template parameter to the constructor. This template template parameter needs to fulfill a range of template arguments and methods:
template<class Type, size_t DOFs>
struct MinimalVector {
Type operator[](size_t i) const; // Array [] getter
Type& operator[](size_t i); // Array [] setter
size_t size() const; // Current size
bool operator==(const MinimalVector<T, DOFs>& rhs) const; // Equal comparison operator
// Only required in combination with DynamicDOFs, e.g. to allocate memory
void resize(size_t size);
};
Note that DynamicDOFs
corresponds to DOFs = 0
. We’ve included a range of examples for using Ruckig with (10) Eigen, (11) custom vector types, and (12) custom types with a dynamic number of DoFs.
Tests and Numerical Stability
The current test suite validates over 5.000.000.000 random trajectories as well as many additional edge cases. The numerical exactness is tested for the final position and final velocity to be within 1e-8
, for the final acceleration to be within 1e-10
, and for the velocity, acceleration and jerk limit to be within of a numerical error of 1e-12
. These are absolute values - we suggest to scale your input so that these correspond to your required precision of the system. For example, for most real-world systems we suggest to use input values in [m]
(instead of e.g. [mm]
), as 1e-8m
is sufficient precise for practical trajectory generation. Furthermore, all kinematic limits should be below 1e9
. The maximal supported trajectory duration is 7e3
. Note that Ruckig will also output values outside of this range, there is however no guarantee for correctness.
The Ruckig Pro version has additional tools to increase the numerical range and improve reliability. For example, theposition_scale
and time_scale
parameter of the Calculator
class change the internal representation of the input parameters.
Ruckig<1> otg;
// Works also for Trackig<1> otg;
otg.calculator.position_scale = 1e2; // Scales all positions in the input parameters
otg.calculator.time_scale = 1e3; // Scale all times in the input parameters
This way, you can easily achieve the requirements above even for very high jerk limits or very long trajectories. Note that the scale parameters don’t effect the resulting trajectory - they are for internal calculation only.
Benchmark
We find that Ruckig is more than twice as fast as Reflexxes Type IV for state-to-state motions and well-suited for control cycles as low as 250 microseconds. The Ruckig Community Version is in general a more powerful and open-source alternative to the Reflexxes Type IV library. In fact, Ruckig is the first Type V trajectory generator for arbitrary target states and even supports directional velocity and acceleration limits, while also being faster on top.
For trajectories with intermediate waypoints, we compare Ruckig to Toppra, a state-of-the-art library for robotic motion planning. Ruckig is able to improve the trajectory duration on average by around 10%, as the path planning and time parametrization are calculated jointly. Moreover, Ruckig is real-time capable and supports jerk-constraints.
Development
Ruckig is written in C++17. It is continuously tested on ubuntu-latest
, macos-latest
, and windows-latest
against following versions
- Doctest v2.4 (only for testing)
- Pybind11 v2.12 (only for Python wrapper)
A C++11 and C++03 version of Ruckig is also available - please contact us if you’re interested.
Used By
Ruckig is used by over hundred research labs, companies, and open-source projects worldwide, including:
- MoveIt 2 for trajectory generation.
- CoppeliaSim starting from version 4.3.
- Fuzzy Logic Robotics
- Gestalt Robotics
- Struckig, a port of Ruckig to Structered Text (ST - IEC61131-3) for usage on PLCs.
- Scanlab for controlling lasers.
- Frankx for controlling the Franka Emika robot arm.
- Wiredworks made a simple Kivy GUI application
- and many others!
Citation
@article{berscheid2021jerk,
title={Jerk-limited Real-time Trajectory Generation with Arbitrary Target States},
author={Berscheid, Lars and Kr{\"o}ger, Torsten},
journal={Robotics: Science and Systems XVII},
year={2021}
}
Changelog for package ruckig
Forthcoming
- [ci] don't check python for c++11
- [ci] move gcc-5 to ubuntu 20.04
- bump version
- add example for per section minimum duration
- Budan's theorem
- use valid profile iterator in step1
- add jerk-minimizing profiles in step2
- fix c++11 patch
- fix c++11 patch
- fix patch c++11
- c++11 fix inplace patching
- improve support for c++11
- update pybind11 in ci
- fix optional in tests with c++11 patch
- update ci checkout version
- fix msvc warning in online calculator
- fix msvc compiler warnings
- expose calculators
- bump version
- performance improvement in step2 vel
- Contributors: pantor
0.8.4 (2022-09-13)
- robustify step2 vel uddu
- fix readme tracking example
- add tracking interface to readme
- fix brake duration reset
- fix brake when current acceleration is on limit
- improve tracking example
- fix pyproject.toml
- clean tracking example
- clean examples
- add pyproject file
- add DOFs to traj serialization
- nlohmann/json based serialization for trajectory
- point out Eigen 3.4 or later
- add custom vector types to readme
- disable vector types example with online client
- include deque
- add examples for custom vector types
- dont support custom data types with online client
- add tests and fixes for custom vector type
- use template specalization without using
- custom vector type as template template parameter
- clean error_at_max_duration, add StandardVector
- clean licenses
- update header dependencies
- clean comparison benchmarks
- extend phase synchronization to velocity control
- move src to src/ruckig
- clean gitignore
- remove -Werror
- Contributors: pantor
0.7.1 (2022-07-10)
- bump to 0.7.1
- fix python 3.10 deployment
- Merge branch 'master' of github.com:pantor/ruckig
- bump to 0.7.0
-
allow user to force new computation for the same input (#132) * allow user to force computation again Otherwise sending the same target with non-zero min_duration multiple times in a control loop will not trigger a new trajectory. * rename to reset Co-authored-by: pantor <<lars.berscheid@online.de>>
- profile precision as constant
- clean notebooks
- fix c++11 std::clamp
- use steady_clock, minor code cleaning of roots.hpp
- fix numeric for time sync with discrete durations
- fix independent min duration with brake trajectory
- clean header includes
- improve stability of velocity control
- msvc warnings
- fix msvc warnings
- static cast for std::div
- Merge branch 'master' of github.com:pantor/ruckig
- fix warnings, limiting_dof to std::optional
- doc: fixed used-by entry (#131)
- move roots into ruckig namespace
- refactor tests and benchmarks
- step2 vel catch root at boundary
- update benchmark plot
- add algorithm header, use c++ array
- make delta_time non const
- add smoothing of non-limiting dofs
- const degrees_of_freedom
- print error messages from online api
- check that current_input is initialized
- Contributors: Matthias Seehauser, Michael Görner, pantor
0.6.5 (2022-03-06)
- revert to manylinux2010_x86_64
- bump to v0.6.5
- fix pypi build from source
- remove 9_trajectory.png
- use .pdf for example trajectories
- numerical stability in velocity control
- fix for zero-to-zero traj with velocity control
- invalidate discrete duration
- fix numerical instability in acc0
- update to nlohmann/json v3.10.5
- bump to 0.6.4
- clarify Online API in examples and Readme
- fix example docs
- fix ci
- build waypoints example only for online client
- add joint example for dynamic dofs and waypoints
- fix capacity / actual waypoints mismatch
- disable ros cd
- retry
- retry
- retry
- debug publish ros
- Contributors: pantor
0.6.3 (2022-01-21)
- bump to v0.6.3
- activaten open_pr for bloom release
- publish ros on release
- test bloom ci
- add bloom release
- several perf optimizations, step2 stability
- clear up waypoints in readme
- fix time sync for discrete durations, rename step1
- Contributors: pantor
0.6.0 (2021-12-06)
- fix python upload
- bump version to 0.6.0
- filter_intermediate_positions
- add braces to if function
- fix error in step 2
- remove filter positions
- remote api for intermediate waypoints
- fix trajectories with zero duration
- use integrated instead target values after traj
- use back() instead of explicit number
- ci build matrix
- BUILD_ONLINE_CLIENT in python package
- add brake in online calculator
- fix ci online-calculator
- auto ci name
- add online calculator for intermediate waypoints
- add httplib and build option
- create third_party directory
- update demo notebook
- update notebook demo
- add jupyter demo notebook
- change brief description of calculator
- expose internal
- add note to ruckig pro examples
- clear up section term
- clean brake class
- refactor integrate to utils
- prepare accel phase
- use dynamic dofs const
- improve input validation
- clean up CD
- Contributors: pantor
0.5.0 (2021-11-14)
- debug publish
- publish pypi package on released release
- bump version
- add hint for Step 1 None
- optimize block class
- improve readme
- per_section_limits in readme
- add per_section_limits
- fix c+11 patch
- fix per dof synchronization
- split CMakeLists examples
- fix per dof synchronization with none
- separate trajectory and calculator class
- fix windows build
- code cleaning
- intermediate waypoints readme
- fix number of waypoints
- avoid pow completely
- update maintainer
- simplify readme
- use brake profile class
- fix finished trajectory for disabled dofs
- minor code cleaning
- Merge branch 'master' of github.com:pantor/ruckig
- add to_string for output parameters (#77)
- add ref to vel add_profile
- positional limits
- min limits for intermediate positions
- extend phase synchronization
- performance improvements
- add section to output in readme
- pass_to_input, did_section_change
- fix nullopt with c++11 patch
- fix nullopt in c++11 patch
- fix c++11
- per dof control interface and synchronization #53
- add section index to output
- Notes about Intermediate Waypoints
- interrupt calculation duration in microseconds
- add ruckig pro examples
- add ruckig toppra comparison
- improve readme and examples
- introduce Ruckig Pro
- remove generate docs ci
- link docs to ruckig.com
- add examples doc pages
- fix example names
- add more examples
- Instantaneous Motion Generation
- add calculation interruption
- add doxyfile again
- step1: numeric stability
- Contributors: Lars Berscheid, lpdon, pantor
0.4.0 (2021-08-23)
- update version to 0.4
- code cleaning
- add was_calculation_interrupted
- step 1: performance optimizations
- interrupt_calculation_duration
- Add CITATION.cff file
(#63)
- add CITATION.cff
- CITATOION wip
- fix cite
- Update README.md
- update to doctest 2.4.6
- code cleaning
- performance optimizations
- step 2: performance optimization
- step 2: performance optimization
- performance optimization: step 1
- performance optimization: positive set of roots
- performance optimization in step1
- code cleaning
- set find_package reflexxes to quiet
- remove BSD license text, why was it there anyway?
- clean plot trajectory
- add printing intermediate_positions
- code cleaning
- add degrees_of_freedom to python trajectory
- rename interface to control_interface
- set_limits for ACC1, code cleaning
- improve numeric stability
- in vel interface, change acc threshold
- code cleanup
- add DynamicDOFs constant
- numerical stability of velocity interface
- improve numerical stability
- fix variable name redeclaration
- fix jerk violation in step2, some optimizations
- clean up check methods of profile
- fix min_velocity with phas e synchronization
- fix phase synchronization in python
- improve numerical stability for high jerks
- fix newton step in acc0/acc1 for t=0
- clean up plot_trajectory
- validate for isnan
- fix python path in examples
- fix position extrema for dynamic number of dofs
- Added python example for non-realtime context
(#43)
- added python example for non-realtime context
- fixed ci workflow
- need to reset t_start
- rename
* change example Co-authored-by: Max Dhom <<md@adva.store>> Co-authored-by: Lars Berscheid <<lars.berscheid@kit.edu>>
- Dynamic Dofs (#47)
- vectorize
- use vector for dof==0
- add tests and checks
- include vector
- default dofs = 0, fix reflexxes
- redo default dofs template parameter
- add readme
- improve readme
- fix grammar
- add tests for invalid input
- add offline trajectory generation
- add paren to get time at position
- add get_first_time_at_position method
- Contributors: Lars Berscheid, Mathis, Max Dhom, pantor
0.3.3 (2021-06-25)
- Merge branch 'master' of github.com:pantor/ruckig
- version 0.3.3
- Set CMAKE_OUTPUT_DIRECTORY for windows build
(#41)
- check windows
- add library
- add debug log
- try to fix
- try to fix2
- try to fix 3
- try to fix 4
- fix 5
- rest test number
- fix setup.py
- remove log
- hard-code build directory of python library
- fix windows packge, version 0.3.2
- pre-compiled packages for windows on pypi
- Contributors: Lars Berscheid, pantor
0.3.1 (2021-06-24)
- set version 0.3.1
- add manifest.in
- double newton step in step2 vel udud
- Fix windows python package
(#38)
- fix windows
- update benchmark figure
- c++11 dont treat warnings as errors
- fix three step
- performance improvements
- vectorize dof
- Fix Patch for C++11
(#36)
- add ci for c++11
- remove maybe_unused
- patch in-place
- fix c++11
- replace make_unique
- find error in ci
- try to fix gcc-5
- dont build python
- dont patch cpp files
- deactivate cmake flags in patch script
- test python example
- add C++11 patch in readme
- add patch script for C++11
- Contributors: Lars Berscheid, pantor
0.3.0 (2021-06-16)
- update version number
- add python at_time comment for doxygen
- check for v_min, fix directional tests
- python return at_time method
- fix max target acceleration
- fix and test extremal positions
- synchronize function to trajectory class
- fix max target acceleration when min_velocity
- clean up docs
- fixed bug in check_position_extremum
(#33)
- fixed copy & paste error in Trajectory::is_phase_synchronizable
- fixed obvious copy & paste error in check_position_extremum
- fixed copy & paste error in Trajectory::is_phase_synchronizable (#32)
- fix negative, near zero pd cases
- Update README.md
- Update README.md
- Update README.md
- check limits with equal sign for numeric stability
- copy jerk_signs for phase synchronization
- remove alternative otgs
- add citation and link to paper
- remove alternative otgs from python
- fix numerical issues on time-optimal traj
- Merge branch 'master' of github.com:pantor/ruckig
- fix numeric error for long durations
- Scale to 5e9 random trajectories
- fix numerical issues
- add step through tests
- fix for braking
- double newton step
- fix macos and windows build
- recalculate after error
- fix some numerical issues
- use checkout@v2 in ci
- use ARCHIVE_OUTPUT_NAME for python wrapper
- msvc: warning as errors
- fix msvc compiler warnings
- Update README.md
- Update README.md
- Fix BUILD_PYTHON_MODULE option on Windows/MSVC (#18)
- fix ci args
- add phase synchronization
- set boundary method
- simplify python example
- Add pip install to Readme
- Contributors: Lars Berscheid, Silvio Traversaro, pantor, stefanbesler
0.2.6 (2021-03-29)
- remove env
- fix python cd
- use static library
- test python executable
- fix python package
- python cd: fix windows
- add setup.py, version 0.2.1
- rename python module to ruckig
- generate python classes for multiple dof
- Add a ROS package manifest (#10) Enables building Ruckig as a plain CMake package in a Catkin/Colcon workspace.
- fix end of brake trajectory integration
- Include GNU install dirs earlier (#11) Otherwise 'CMAKE_INSTALL_INCLUDEDIR' is empty/undefined when it's used to setup ruckig::ruckig's target_include_directories(..).
- readme: some minor typos (#9) I happened to notice them.
- privatize trajectory class members
- privatize some class members
- use cmath
- code cleaning
- show enum in docs
- split parameter files, calculate in trajectory
- code cleaning
- add python example
- Move options to API documentation
- Fix Readme Code
- fix undefined output for zero duration
- indicate default values in Readme
- add discrete durations
- Add Windows and macOS build to CI
(#4)
- windows and mac ci
- use cmake action for generator
- fix ci build directory
- run tests only on linux
- test example
- Add support to compile on Windows (#3)
- Merge pull request #2 from traversaro/patch-1 Use BUILD_SHARED_LIBS to select if compile C++ library as static or shared
- document examples/CMakeLists.txt
- add ci to PRs
- Use BUILD_SHARED_LIBS to select if compile as static or shared
- Merge pull request #1 from traversaro/add-install-support Add support for installation of the C++ library
- Add support for installation of the C++ library
- set correct cmake and doxygen version
- fix more edge cases
- fix some edge cases
- document velocity interface
- added velocity interface
- improve readme
- improve benchmark
- fix finding subdirectory
- check ci
- build python module in ci
- use own set class on stack
- fix synchronization enum, better python support
- add time synchronization parameter
- fix motion finished reset
- fix immediate reaction
- fix more edge cases
- refine min acceleration
- add min_acceleration
- fix some edge cases
- Merge branch 'master' of github.com:pantor/ruckig
- decrease required cmake to 3.10
- fix ci
- introduce trajectory class
- position extrema
- scale tests to 1e9
- several optimizations
- compile with warnings
- step2: code cleaning
- fix numeric edge cases
- move test suite to doctest
- fix cmake as submodule
- Merge branch 'master' of github.com:pantor/ruckig
- fix optional minimum time
- code documentation, more tests
- fix benchmark
- build benchmark in ci
- fix gcc
- remove eigen dep in cmake
- code cleaning
- code cleaning
- add comparison with multiple DoF
- rix ci: braking
- fix interval selection
- clean braking
- fix ci, more tests
- add benchmark, numeric stability
- fix block in step1
- clean root finding
- Increase stability
- improve tests, remove eigen
- code style
- increase test coverage
- add min_velocity
- fix ci
- Step1: Use Newton step
- fix ci
- fix time sync
- update tests
- more tests
- add example
- more tests
- increase number of tests
- simplify equations
- simplify equations
- simplify equations
- add tuple header
- further code cleaning
- remove eigen dependency, code cleaning
- clean brake code
- code cleaning
- code cleaning
- add doxygen
- improve acceleration target, readme
- refine max time deviation to 1e-8
- code cleaning
- improve time sync
- block synchronization
- stability for target acceleration in 1 dof
- update readme for ruckig
- add license
- improve tests
- fix eigen ci folder name
- fix eigen git repository
- fix 1dof vf comparison
- remove complex algorithmic
- code cleaning
- initial commit
- Contributors: G.A. vd. Hoorn, Lars Berscheid, Silvio Traversaro, pantor
Wiki Tutorials
Dependant Packages
Name | Deps |
---|---|
moveit_core |
Launch files
Messages
Services
Plugins
Recent questions tagged ruckig at Robotics Stack Exchange
Package Summary
Tags | No category tags. |
Version | 0.14.0 |
License | MIT |
Build type | CMAKE |
Use | RECOMMENDED |
Repository Summary
Checkout URI | https://github.com/pantor/ruckig.git |
VCS Type | git |
VCS Version | main |
Last Updated | 2024-12-08 |
Dev Status | DEVELOPED |
CI status | No Continuous Integration |
Released | RELEASED |
Tags | No category tags. |
Contributing |
Help Wanted (0)
Good First Issues (0) Pull Requests to Review (0) |
Package Description
Additional Links
Maintainers
- Lars Berscheid
Authors
- Lars Berscheid
Ruckig
Instantaneous Motion Generation for Robots and Machines.
Ruckig generates trajectories on-the-fly, allowing robots and machines to react instantaneously to sensor input. Ruckig calculates a trajectory to a target waypoint (with position, velocity, and acceleration) starting from any initial state limited by velocity, acceleration, and jerk constraints. Besides the target state, Ruckig allows to define intermediate positions for waypoint following. For state-to-state motions, Ruckig guarantees a time-optimal solution. With intermediate waypoints, Ruckig calculates the path and its time parametrization jointly, resulting in significantly faster trajectories compared to traditional methods.
More information can be found at ruckig.com and in the corresponding paper Jerk-limited Real-time Trajectory Generation with Arbitrary Target States, accepted for the Robotics: Science and Systems (RSS), 2021 conference.
Installation
Ruckig has no dependencies (except for testing). To build Ruckig using CMake, just run
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
To install Ruckig in a system-wide directory, you can either use (sudo) make install
or install it as debian package using cpack by running
cpack
sudo dpkg -i ruckig*.deb
An example of using Ruckig in your CMake project is given by examples/CMakeLists.txt
. However, you can also include Ruckig as a directory within your project and call add_subdirectory(ruckig)
in your parent CMakeLists.txt
.
Ruckig is also available as a Python module, in particular for development or debugging purposes. The Ruckig Community Version can be installed from PyPI via
pip install ruckig
When using CMake, the Python module can be built using the BUILD_PYTHON_MODULE
flag. If you’re only interested in the Python module (and not in the C++ library), you can build and install Ruckig via pip install .
.
Tutorial
Furthermore, we will explain the basics to get started with online generated trajectories within your application. There is also a collection of examples that guide you through the most important features of Ruckig. A time-optimal trajectory for a single degree of freedom is shown in the figure below. We also added plots of the resulting trajectories for all examples. Let’s get started!
Waypoint-based Trajectory Generation
Ruckig provides three main interface classes: the Ruckig, the InputParameter, and the OutputParameter class.
First, you’ll need to create a Ruckig instance with the number of DoFs as a template parameter, and the control cycle (e.g. in seconds) in the constructor.
Ruckig<6> ruckig {0.001}; // Number DoFs; control cycle in [s]
The input type has 3 blocks of data: the current state, the target state and the corresponding kinematic limits.
InputParameter<6> input; // Number DoFs
input.current_position = {0.2, ...};
input.current_velocity = {0.1, ...};
input.current_acceleration = {0.1, ...};
input.target_position = {0.5, ...};
input.target_velocity = {-0.1, ...};
input.target_acceleration = {0.2, ...};
input.max_velocity = {0.4, ...};
input.max_acceleration = {1.0, ...};
input.max_jerk = {4.0, ...};
OutputParameter<6> output; // Number DoFs
If you only want to have a acceleration-constrained trajectory, you can also omit the max_jerk
as well as the current
and target_acceleration
value. Given all input and output resources, we can iterate over the trajectory at each discrete time step. For most applications, this loop must run within a real-time thread and controls the actual hardware.
while (ruckig.update(input, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
output.pass_to_input(input); // Don't forget this!
}
Within the control loop, you need to update the current state of the input parameter according to the calculated trajectory. Therefore, the pass_to_input
method copies the new kinematic state of the output to the current kinematic state of the input parameter. If (in the next step) the current state is not the expected, pre-calculated trajectory, Ruckig will calculate a new trajectory based on the novel input. When the trajectory has reached the target state, the update
function will return Result::Finished
.
Intermediate Waypoints
The Ruckig Community Version now supports intermediate waypoints via a cloud API. To allocate the necessary memory for a variable number of waypoints beforehand, we need to pass the maximum number of waypoints to Ruckig via
Ruckig<6> otg {0.001, 8};
InputParameter<6> input {8};
OutputParameter<6> output {8};
The InputParameter
class takes the number of waypoints as an optional input, however usually you will fill in the values (and therefore reserve its memory) yourself. Then you’re ready to set intermediate via points by
input.intermediate_positions = {
{0.2, ...},
{0.8, ...},
};
As soon as at least one intermediate positions is given, the Ruckig Community Version switches to the mentioned (of course, non real-time capable) cloud API. If you require real-time calculation on your own hardware, please contact us for the Ruckig Pro Version.
When using intermediate positions, both the underlying motion planning problem as well as its calculation changes significantly. In particular, there are some fundamental limitations for jerk-limited online trajectory generation regarding the usage of waypoints. Please find more information about these limitations here, and in general we recommend to use
input.intermediate_positions = otg.filter_intermediate_positions(input.intermediate_positions, {0.1, ...});
to filter waypoints according to a (high) threshold distance. Setting interrupt_calculation_duration makes sure to be real-time capable by refining the solution in the next control invocation. Note that this is a soft interruption of the calculation. Currently, no minimum or discrete durations are supported when using intermediate positions.
Input Parameter
To go into more detail, the InputParameter type has following members:
using Vector = std::array<double, DOFs>; // By default
Vector current_position;
Vector current_velocity; // Initialized to zero
Vector current_acceleration; // Initialized to zero
std::vector<Vector> intermediate_positions; // (only in Pro Version)
Vector target_position;
Vector target_velocity; // Initialized to zero
Vector target_acceleration; // Initialized to zero
Vector max_velocity;
Vector max_acceleration;
Vector max_jerk; // Initialized to infinity
std::optional<Vector> min_velocity; // If not given, the negative maximum velocity will be used.
std::optional<Vector> min_acceleration; // If not given, the negative maximum acceleration will be used.
std::optional<Vector> min_position; // (only in Pro Version)
std::optional<Vector> max_position; // (only in Pro Version)
std::array<bool, DOFs> enabled; // Initialized to true
std::optional<double> minimum_duration;
std::optional<double> interrupt_calculation_duration; // [µs], (only in Pro Version)
ControlInterface control_interface; // The default position interface controls the full kinematic state.
Synchronization synchronization; // Synchronization behavior of multiple DoFs
DurationDiscretization duration_discretization; // Whether the duration should be a discrete multiple of the control cycle (off by default)
std::optional<Vector<ControlInterface>> per_dof_control_interface; // Sets the control interface for each DoF individually, overwrites global control_interface
std::optional<Vector<Synchronization>> per_dof_synchronization; // Sets the synchronization for each DoF individually, overwrites global synchronization
On top of the current state, target state, and constraints, Ruckig allows for a few more advanced settings:
- A minimum velocity and acceleration can be specified - these should be a negative number. If they are not given, the negative maximum velocity or acceleration will be used (similar to the jerk limit). For example, this might be useful in human robot collaboration settings with a different velocity limit towards a human. Or, when switching between different moving coordinate frames like picking from a conveyer belt.
- You can overwrite the global kinematic limits to specify limits for each section between two waypoints separately by using e.g.
per_section_max_velocity
. - If a DoF is not enabled, it will be ignored in the calculation. Ruckig will output a trajectory with constant acceleration for those DoFs.
- A minimum duration can be optionally given. Note that Ruckig can not guarantee an exact, but only a minimum duration of the trajectory.
- The control interface (position or velocity control) can be switched easily. For example, a stop trajectory or visual servoing can be easily implemented with the velocity interface.
- Different synchronization behaviors (i.a. phase, time, or no synchonization) are implemented. Phase synchronization results in straight-line motions.
- The trajectory duration might be constrained to a multiple of the control cycle. This way, the exact state can be reached at a control loop execution.
We refer to the API documentation of the enumerations within the ruckig
namespace for all available options.
Input Validation
To check that Ruckig is able to generate a trajectory before the actual calculation step,
ruckig.validate_input(input, check_current_state_within_limits=false, check_target_state_within_limits=true);
// returns true or throws
throws an error with a detailed reason if an input is not valid. You can also set the default template parameter to false via ruckig.validate_input<false>(...)
to just return a boolean true or false. The two boolean arguments check that the current or target state are within the limits. The check includes a typical catch of jerk-limited trajectory generation: When the current state is at maximal velocity, any positive acceleration will inevitable lead to a velocity violation at a future timestep. In general, this condition is fulfilled when
Abs(acceleration) <= Sqrt(2 * max_jerk * (max_velocity - Abs(velocity))).
If both arguments are set to true, the calculated trajectory is guaranteed to be within the kinematic limits throughout its duration. Also, note that there are range constraints of the input due to numerical reasons, see below for more details.
Result Type
The update
function of the Ruckig class returns a Result type that indicates the current state of the algorithm. This can either be working, finished if the trajectory has finished, or an error type if something went wrong during calculation. The result type can be compared as a standard integer.
State | Error Code |
---|---|
Working | 0 |
Finished | 1 |
Error | -1 |
ErrorInvalidInput | -100 |
ErrorTrajectoryDuration | -101 |
ErrorPositionalLimits | -102 |
ErrorExecutionTimeCalculation | -110 |
ErrorSynchronizationCalculation | -111 |
Output Parameter
The output class includes the new kinematic state and the overall trajectory.
Vector new_position;
Vector new_velocity;
Vector new_acceleration;
Trajectory trajectory; // The current trajectory
double time; // The current, auto-incremented time. Reset to 0 at a new calculation.
size_t new_section; // Index of the section between two (possibly filtered) intermediate positions.
bool did_section_change; // Was a new section reached in the last cycle?
bool new_calculation; // Whether a new calculation was performed in the last cycle
bool was_calculation_interrupted; // Was the trajectory calculation interrupted? (only in Pro Version)
double calculation_duration; // Duration of the calculation in the last cycle [µs]
Moreover, the trajectory class has a range of useful parameters and methods.
double duration; // Duration of the trajectory
std::array<double, DOFs> independent_min_durations; // Time-optimal profile for each independent DoF
<...> at_time(double time); // Get the kinematic state of the trajectory at a given time
<...> get_position_extrema(); // Returns information about the position extrema and their times
Again, we refer to the API documentation for the exact signatures.
Offline Calculation
Ruckig also supports an offline approach for calculating a trajectory:
result = ruckig.calculate(input, trajectory);
When only using this method, the Ruckig
constructor does not need a control cycle (delta_time
) as an argument. However if given, Ruckig supports stepping through the trajectory with
while (ruckig.update(trajectory, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
}
starting from the current output.time
(currently Ruckig Pro only).
Tracking Interface
When following an arbitrary signal with position, velocity, acceleration, and jerk-limitation, the straight forward way would be to pass the current state to Ruckig’s target state. However, as the resulting trajectory will take time to catch up, this approach will always lag behind the signal. The tracking interface solves this problem by predicting ahead (e.g. with constant acceleration by default) and is therefore able to follow signals very closely in a time-optimal way. This might be very helpful for (general) tracking, robot servoing, or trajectory post-processing applications.
To use the tracking interface, construct
Trackig<1> otg {0.01}; // control cycle
and set the current state as well as the kinematic constraints via
input.current_position = {0.0};
input.current_velocity = {0.0};
input.current_acceleration = {0.0};
input.max_velocity = {0.8};
input.max_acceleration = {2.0};
input.max_jerk = {5.0};
Then, we can track a signal in an online manner within the real-time control loop
for (double t = 0; t < 10.0; t += otg.delta_time) {
auto target_state = signal(t); // signal returns position, velocity, and acceleration
auto res = otg.update(target_state, input, output);
// Make use of the smooth target motion here (e.g. output.new_position)
output.pass_to_input(input);
}
Please find a complete example here. This functionality can also be used in an offline manner, e.g. when the entire signal is known beforehand. Here, we call the
smooth_trajectory = otg.calculate_trajectory(target_states, input);
method with the trajectory given as a std::vector
of target states. The Tracking interface is available in the Ruckig Pro version.
Dynamic Number of Degrees of Freedom
So far, we have told Ruckig the number of DoFs as a template parameter. If you don’t know the number of DoFs at compile-time, you can set the template parameter to ruckig::DynamicDOFs
and pass the DoFs to the constructor:
Ruckig<DynamicDOFs> otg {6, 0.001};
InputParameter<DynamicDOFs> input {6};
OutputParameter<DynamicDOFs> output {6};
This switches the default Vector from the std::array
to the dynamic std::vector
type. However, we recommend to keep the template parameter when possible: First, it has a performance benefit of a few percent. Second, it is convenient for real-time programming due to its easier handling of memory allocations. When using dynamic degrees of freedom, make sure to allocate the memory of all vectors beforehand.
Custom Vector Types
Ruckig supports custom vector types to make interfacing with your code even easier and more flexible. Most importantly, you can switch to Eigen Vectors simply by including Eigen (3.4 or later) before Ruckig
#include <Eigen/Core> // Version 3.4 or later
#include <ruckig/ruckig.hpp>
and then call the constructors with the ruckig::EigenVector
parameter.
Ruckig<6, EigenVector> otg {0.001};
InputParameter<6, EigenVector> input;
OutputParameter<6, EigenVector> output;
Now every in- and output of Ruckig’s API (such as current_position
, new_position
or max_jerk
) are Eigen types! To define completely custom vector types, you can pass a C++ template template parameter to the constructor. This template template parameter needs to fulfill a range of template arguments and methods:
template<class Type, size_t DOFs>
struct MinimalVector {
Type operator[](size_t i) const; // Array [] getter
Type& operator[](size_t i); // Array [] setter
size_t size() const; // Current size
bool operator==(const MinimalVector<T, DOFs>& rhs) const; // Equal comparison operator
// Only required in combination with DynamicDOFs, e.g. to allocate memory
void resize(size_t size);
};
Note that DynamicDOFs
corresponds to DOFs = 0
. We’ve included a range of examples for using Ruckig with (10) Eigen, (11) custom vector types, and (12) custom types with a dynamic number of DoFs.
Tests and Numerical Stability
The current test suite validates over 5.000.000.000 random trajectories as well as many additional edge cases. The numerical exactness is tested for the final position and final velocity to be within 1e-8
, for the final acceleration to be within 1e-10
, and for the velocity, acceleration and jerk limit to be within of a numerical error of 1e-12
. These are absolute values - we suggest to scale your input so that these correspond to your required precision of the system. For example, for most real-world systems we suggest to use input values in [m]
(instead of e.g. [mm]
), as 1e-8m
is sufficient precise for practical trajectory generation. Furthermore, all kinematic limits should be below 1e9
. The maximal supported trajectory duration is 7e3
. Note that Ruckig will also output values outside of this range, there is however no guarantee for correctness.
The Ruckig Pro version has additional tools to increase the numerical range and improve reliability. For example, theposition_scale
and time_scale
parameter of the Calculator
class change the internal representation of the input parameters.
Ruckig<1> otg;
// Works also for Trackig<1> otg;
otg.calculator.position_scale = 1e2; // Scales all positions in the input parameters
otg.calculator.time_scale = 1e3; // Scale all times in the input parameters
This way, you can easily achieve the requirements above even for very high jerk limits or very long trajectories. Note that the scale parameters don’t effect the resulting trajectory - they are for internal calculation only.
Benchmark
We find that Ruckig is more than twice as fast as Reflexxes Type IV for state-to-state motions and well-suited for control cycles as low as 250 microseconds. The Ruckig Community Version is in general a more powerful and open-source alternative to the Reflexxes Type IV library. In fact, Ruckig is the first Type V trajectory generator for arbitrary target states and even supports directional velocity and acceleration limits, while also being faster on top.
For trajectories with intermediate waypoints, we compare Ruckig to Toppra, a state-of-the-art library for robotic motion planning. Ruckig is able to improve the trajectory duration on average by around 10%, as the path planning and time parametrization are calculated jointly. Moreover, Ruckig is real-time capable and supports jerk-constraints.
Development
Ruckig is written in C++17. It is continuously tested on ubuntu-latest
, macos-latest
, and windows-latest
against following versions
- Doctest v2.4 (only for testing)
- Pybind11 v2.12 (only for Python wrapper)
A C++11 and C++03 version of Ruckig is also available - please contact us if you’re interested.
Used By
Ruckig is used by over hundred research labs, companies, and open-source projects worldwide, including:
- MoveIt 2 for trajectory generation.
- CoppeliaSim starting from version 4.3.
- Fuzzy Logic Robotics
- Gestalt Robotics
- Struckig, a port of Ruckig to Structered Text (ST - IEC61131-3) for usage on PLCs.
- Scanlab for controlling lasers.
- Frankx for controlling the Franka Emika robot arm.
- Wiredworks made a simple Kivy GUI application
- and many others!
Citation
@article{berscheid2021jerk,
title={Jerk-limited Real-time Trajectory Generation with Arbitrary Target States},
author={Berscheid, Lars and Kr{\"o}ger, Torsten},
journal={Robotics: Science and Systems XVII},
year={2021}
}
Changelog for package ruckig
Forthcoming
- [ci] don't check python for c++11
- [ci] move gcc-5 to ubuntu 20.04
- bump version
- add example for per section minimum duration
- Budan's theorem
- use valid profile iterator in step1
- add jerk-minimizing profiles in step2
- fix c++11 patch
- fix c++11 patch
- fix patch c++11
- c++11 fix inplace patching
- improve support for c++11
- update pybind11 in ci
- fix optional in tests with c++11 patch
- update ci checkout version
- fix msvc warning in online calculator
- fix msvc compiler warnings
- expose calculators
- bump version
- performance improvement in step2 vel
- Contributors: pantor
0.8.4 (2022-09-13)
- robustify step2 vel uddu
- fix readme tracking example
- add tracking interface to readme
- fix brake duration reset
- fix brake when current acceleration is on limit
- improve tracking example
- fix pyproject.toml
- clean tracking example
- clean examples
- add pyproject file
- add DOFs to traj serialization
- nlohmann/json based serialization for trajectory
- point out Eigen 3.4 or later
- add custom vector types to readme
- disable vector types example with online client
- include deque
- add examples for custom vector types
- dont support custom data types with online client
- add tests and fixes for custom vector type
- use template specalization without using
- custom vector type as template template parameter
- clean error_at_max_duration, add StandardVector
- clean licenses
- update header dependencies
- clean comparison benchmarks
- extend phase synchronization to velocity control
- move src to src/ruckig
- clean gitignore
- remove -Werror
- Contributors: pantor
0.7.1 (2022-07-10)
- bump to 0.7.1
- fix python 3.10 deployment
- Merge branch 'master' of github.com:pantor/ruckig
- bump to 0.7.0
-
allow user to force new computation for the same input (#132) * allow user to force computation again Otherwise sending the same target with non-zero min_duration multiple times in a control loop will not trigger a new trajectory. * rename to reset Co-authored-by: pantor <<lars.berscheid@online.de>>
- profile precision as constant
- clean notebooks
- fix c++11 std::clamp
- use steady_clock, minor code cleaning of roots.hpp
- fix numeric for time sync with discrete durations
- fix independent min duration with brake trajectory
- clean header includes
- improve stability of velocity control
- msvc warnings
- fix msvc warnings
- static cast for std::div
- Merge branch 'master' of github.com:pantor/ruckig
- fix warnings, limiting_dof to std::optional
- doc: fixed used-by entry (#131)
- move roots into ruckig namespace
- refactor tests and benchmarks
- step2 vel catch root at boundary
- update benchmark plot
- add algorithm header, use c++ array
- make delta_time non const
- add smoothing of non-limiting dofs
- const degrees_of_freedom
- print error messages from online api
- check that current_input is initialized
- Contributors: Matthias Seehauser, Michael Görner, pantor
0.6.5 (2022-03-06)
- revert to manylinux2010_x86_64
- bump to v0.6.5
- fix pypi build from source
- remove 9_trajectory.png
- use .pdf for example trajectories
- numerical stability in velocity control
- fix for zero-to-zero traj with velocity control
- invalidate discrete duration
- fix numerical instability in acc0
- update to nlohmann/json v3.10.5
- bump to 0.6.4
- clarify Online API in examples and Readme
- fix example docs
- fix ci
- build waypoints example only for online client
- add joint example for dynamic dofs and waypoints
- fix capacity / actual waypoints mismatch
- disable ros cd
- retry
- retry
- retry
- debug publish ros
- Contributors: pantor
0.6.3 (2022-01-21)
- bump to v0.6.3
- activaten open_pr for bloom release
- publish ros on release
- test bloom ci
- add bloom release
- several perf optimizations, step2 stability
- clear up waypoints in readme
- fix time sync for discrete durations, rename step1
- Contributors: pantor
0.6.0 (2021-12-06)
- fix python upload
- bump version to 0.6.0
- filter_intermediate_positions
- add braces to if function
- fix error in step 2
- remove filter positions
- remote api for intermediate waypoints
- fix trajectories with zero duration
- use integrated instead target values after traj
- use back() instead of explicit number
- ci build matrix
- BUILD_ONLINE_CLIENT in python package
- add brake in online calculator
- fix ci online-calculator
- auto ci name
- add online calculator for intermediate waypoints
- add httplib and build option
- create third_party directory
- update demo notebook
- update notebook demo
- add jupyter demo notebook
- change brief description of calculator
- expose internal
- add note to ruckig pro examples
- clear up section term
- clean brake class
- refactor integrate to utils
- prepare accel phase
- use dynamic dofs const
- improve input validation
- clean up CD
- Contributors: pantor
0.5.0 (2021-11-14)
- debug publish
- publish pypi package on released release
- bump version
- add hint for Step 1 None
- optimize block class
- improve readme
- per_section_limits in readme
- add per_section_limits
- fix c+11 patch
- fix per dof synchronization
- split CMakeLists examples
- fix per dof synchronization with none
- separate trajectory and calculator class
- fix windows build
- code cleaning
- intermediate waypoints readme
- fix number of waypoints
- avoid pow completely
- update maintainer
- simplify readme
- use brake profile class
- fix finished trajectory for disabled dofs
- minor code cleaning
- Merge branch 'master' of github.com:pantor/ruckig
- add to_string for output parameters (#77)
- add ref to vel add_profile
- positional limits
- min limits for intermediate positions
- extend phase synchronization
- performance improvements
- add section to output in readme
- pass_to_input, did_section_change
- fix nullopt with c++11 patch
- fix nullopt in c++11 patch
- fix c++11
- per dof control interface and synchronization #53
- add section index to output
- Notes about Intermediate Waypoints
- interrupt calculation duration in microseconds
- add ruckig pro examples
- add ruckig toppra comparison
- improve readme and examples
- introduce Ruckig Pro
- remove generate docs ci
- link docs to ruckig.com
- add examples doc pages
- fix example names
- add more examples
- Instantaneous Motion Generation
- add calculation interruption
- add doxyfile again
- step1: numeric stability
- Contributors: Lars Berscheid, lpdon, pantor
0.4.0 (2021-08-23)
- update version to 0.4
- code cleaning
- add was_calculation_interrupted
- step 1: performance optimizations
- interrupt_calculation_duration
- Add CITATION.cff file
(#63)
- add CITATION.cff
- CITATOION wip
- fix cite
- Update README.md
- update to doctest 2.4.6
- code cleaning
- performance optimizations
- step 2: performance optimization
- step 2: performance optimization
- performance optimization: step 1
- performance optimization: positive set of roots
- performance optimization in step1
- code cleaning
- set find_package reflexxes to quiet
- remove BSD license text, why was it there anyway?
- clean plot trajectory
- add printing intermediate_positions
- code cleaning
- add degrees_of_freedom to python trajectory
- rename interface to control_interface
- set_limits for ACC1, code cleaning
- improve numeric stability
- in vel interface, change acc threshold
- code cleanup
- add DynamicDOFs constant
- numerical stability of velocity interface
- improve numerical stability
- fix variable name redeclaration
- fix jerk violation in step2, some optimizations
- clean up check methods of profile
- fix min_velocity with phas e synchronization
- fix phase synchronization in python
- improve numerical stability for high jerks
- fix newton step in acc0/acc1 for t=0
- clean up plot_trajectory
- validate for isnan
- fix python path in examples
- fix position extrema for dynamic number of dofs
- Added python example for non-realtime context
(#43)
- added python example for non-realtime context
- fixed ci workflow
- need to reset t_start
- rename
* change example Co-authored-by: Max Dhom <<md@adva.store>> Co-authored-by: Lars Berscheid <<lars.berscheid@kit.edu>>
- Dynamic Dofs (#47)
- vectorize
- use vector for dof==0
- add tests and checks
- include vector
- default dofs = 0, fix reflexxes
- redo default dofs template parameter
- add readme
- improve readme
- fix grammar
- add tests for invalid input
- add offline trajectory generation
- add paren to get time at position
- add get_first_time_at_position method
- Contributors: Lars Berscheid, Mathis, Max Dhom, pantor
0.3.3 (2021-06-25)
- Merge branch 'master' of github.com:pantor/ruckig
- version 0.3.3
- Set CMAKE_OUTPUT_DIRECTORY for windows build
(#41)
- check windows
- add library
- add debug log
- try to fix
- try to fix2
- try to fix 3
- try to fix 4
- fix 5
- rest test number
- fix setup.py
- remove log
- hard-code build directory of python library
- fix windows packge, version 0.3.2
- pre-compiled packages for windows on pypi
- Contributors: Lars Berscheid, pantor
0.3.1 (2021-06-24)
- set version 0.3.1
- add manifest.in
- double newton step in step2 vel udud
- Fix windows python package
(#38)
- fix windows
- update benchmark figure
- c++11 dont treat warnings as errors
- fix three step
- performance improvements
- vectorize dof
- Fix Patch for C++11
(#36)
- add ci for c++11
- remove maybe_unused
- patch in-place
- fix c++11
- replace make_unique
- find error in ci
- try to fix gcc-5
- dont build python
- dont patch cpp files
- deactivate cmake flags in patch script
- test python example
- add C++11 patch in readme
- add patch script for C++11
- Contributors: Lars Berscheid, pantor
0.3.0 (2021-06-16)
- update version number
- add python at_time comment for doxygen
- check for v_min, fix directional tests
- python return at_time method
- fix max target acceleration
- fix and test extremal positions
- synchronize function to trajectory class
- fix max target acceleration when min_velocity
- clean up docs
- fixed bug in check_position_extremum
(#33)
- fixed copy & paste error in Trajectory::is_phase_synchronizable
- fixed obvious copy & paste error in check_position_extremum
- fixed copy & paste error in Trajectory::is_phase_synchronizable (#32)
- fix negative, near zero pd cases
- Update README.md
- Update README.md
- Update README.md
- check limits with equal sign for numeric stability
- copy jerk_signs for phase synchronization
- remove alternative otgs
- add citation and link to paper
- remove alternative otgs from python
- fix numerical issues on time-optimal traj
- Merge branch 'master' of github.com:pantor/ruckig
- fix numeric error for long durations
- Scale to 5e9 random trajectories
- fix numerical issues
- add step through tests
- fix for braking
- double newton step
- fix macos and windows build
- recalculate after error
- fix some numerical issues
- use checkout@v2 in ci
- use ARCHIVE_OUTPUT_NAME for python wrapper
- msvc: warning as errors
- fix msvc compiler warnings
- Update README.md
- Update README.md
- Fix BUILD_PYTHON_MODULE option on Windows/MSVC (#18)
- fix ci args
- add phase synchronization
- set boundary method
- simplify python example
- Add pip install to Readme
- Contributors: Lars Berscheid, Silvio Traversaro, pantor, stefanbesler
0.2.6 (2021-03-29)
- remove env
- fix python cd
- use static library
- test python executable
- fix python package
- python cd: fix windows
- add setup.py, version 0.2.1
- rename python module to ruckig
- generate python classes for multiple dof
- Add a ROS package manifest (#10) Enables building Ruckig as a plain CMake package in a Catkin/Colcon workspace.
- fix end of brake trajectory integration
- Include GNU install dirs earlier (#11) Otherwise 'CMAKE_INSTALL_INCLUDEDIR' is empty/undefined when it's used to setup ruckig::ruckig's target_include_directories(..).
- readme: some minor typos (#9) I happened to notice them.
- privatize trajectory class members
- privatize some class members
- use cmath
- code cleaning
- show enum in docs
- split parameter files, calculate in trajectory
- code cleaning
- add python example
- Move options to API documentation
- Fix Readme Code
- fix undefined output for zero duration
- indicate default values in Readme
- add discrete durations
- Add Windows and macOS build to CI
(#4)
- windows and mac ci
- use cmake action for generator
- fix ci build directory
- run tests only on linux
- test example
- Add support to compile on Windows (#3)
- Merge pull request #2 from traversaro/patch-1 Use BUILD_SHARED_LIBS to select if compile C++ library as static or shared
- document examples/CMakeLists.txt
- add ci to PRs
- Use BUILD_SHARED_LIBS to select if compile as static or shared
- Merge pull request #1 from traversaro/add-install-support Add support for installation of the C++ library
- Add support for installation of the C++ library
- set correct cmake and doxygen version
- fix more edge cases
- fix some edge cases
- document velocity interface
- added velocity interface
- improve readme
- improve benchmark
- fix finding subdirectory
- check ci
- build python module in ci
- use own set class on stack
- fix synchronization enum, better python support
- add time synchronization parameter
- fix motion finished reset
- fix immediate reaction
- fix more edge cases
- refine min acceleration
- add min_acceleration
- fix some edge cases
- Merge branch 'master' of github.com:pantor/ruckig
- decrease required cmake to 3.10
- fix ci
- introduce trajectory class
- position extrema
- scale tests to 1e9
- several optimizations
- compile with warnings
- step2: code cleaning
- fix numeric edge cases
- move test suite to doctest
- fix cmake as submodule
- Merge branch 'master' of github.com:pantor/ruckig
- fix optional minimum time
- code documentation, more tests
- fix benchmark
- build benchmark in ci
- fix gcc
- remove eigen dep in cmake
- code cleaning
- code cleaning
- add comparison with multiple DoF
- rix ci: braking
- fix interval selection
- clean braking
- fix ci, more tests
- add benchmark, numeric stability
- fix block in step1
- clean root finding
- Increase stability
- improve tests, remove eigen
- code style
- increase test coverage
- add min_velocity
- fix ci
- Step1: Use Newton step
- fix ci
- fix time sync
- update tests
- more tests
- add example
- more tests
- increase number of tests
- simplify equations
- simplify equations
- simplify equations
- add tuple header
- further code cleaning
- remove eigen dependency, code cleaning
- clean brake code
- code cleaning
- code cleaning
- add doxygen
- improve acceleration target, readme
- refine max time deviation to 1e-8
- code cleaning
- improve time sync
- block synchronization
- stability for target acceleration in 1 dof
- update readme for ruckig
- add license
- improve tests
- fix eigen ci folder name
- fix eigen git repository
- fix 1dof vf comparison
- remove complex algorithmic
- code cleaning
- initial commit
- Contributors: G.A. vd. Hoorn, Lars Berscheid, Silvio Traversaro, pantor
Wiki Tutorials
Dependant Packages
Name | Deps |
---|---|
moveit_core |
Launch files
Messages
Services
Plugins
Recent questions tagged ruckig at Robotics Stack Exchange
Package Summary
Tags | No category tags. |
Version | 0.14.0 |
License | MIT |
Build type | CMAKE |
Use | RECOMMENDED |
Repository Summary
Checkout URI | https://github.com/pantor/ruckig.git |
VCS Type | git |
VCS Version | main |
Last Updated | 2024-12-08 |
Dev Status | DEVELOPED |
CI status | No Continuous Integration |
Released | RELEASED |
Tags | No category tags. |
Contributing |
Help Wanted (0)
Good First Issues (0) Pull Requests to Review (0) |
Package Description
Additional Links
Maintainers
- Lars Berscheid
Authors
- Lars Berscheid
Ruckig
Instantaneous Motion Generation for Robots and Machines.
Ruckig generates trajectories on-the-fly, allowing robots and machines to react instantaneously to sensor input. Ruckig calculates a trajectory to a target waypoint (with position, velocity, and acceleration) starting from any initial state limited by velocity, acceleration, and jerk constraints. Besides the target state, Ruckig allows to define intermediate positions for waypoint following. For state-to-state motions, Ruckig guarantees a time-optimal solution. With intermediate waypoints, Ruckig calculates the path and its time parametrization jointly, resulting in significantly faster trajectories compared to traditional methods.
More information can be found at ruckig.com and in the corresponding paper Jerk-limited Real-time Trajectory Generation with Arbitrary Target States, accepted for the Robotics: Science and Systems (RSS), 2021 conference.
Installation
Ruckig has no dependencies (except for testing). To build Ruckig using CMake, just run
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
To install Ruckig in a system-wide directory, you can either use (sudo) make install
or install it as debian package using cpack by running
cpack
sudo dpkg -i ruckig*.deb
An example of using Ruckig in your CMake project is given by examples/CMakeLists.txt
. However, you can also include Ruckig as a directory within your project and call add_subdirectory(ruckig)
in your parent CMakeLists.txt
.
Ruckig is also available as a Python module, in particular for development or debugging purposes. The Ruckig Community Version can be installed from PyPI via
pip install ruckig
When using CMake, the Python module can be built using the BUILD_PYTHON_MODULE
flag. If you’re only interested in the Python module (and not in the C++ library), you can build and install Ruckig via pip install .
.
Tutorial
Furthermore, we will explain the basics to get started with online generated trajectories within your application. There is also a collection of examples that guide you through the most important features of Ruckig. A time-optimal trajectory for a single degree of freedom is shown in the figure below. We also added plots of the resulting trajectories for all examples. Let’s get started!
Waypoint-based Trajectory Generation
Ruckig provides three main interface classes: the Ruckig, the InputParameter, and the OutputParameter class.
First, you’ll need to create a Ruckig instance with the number of DoFs as a template parameter, and the control cycle (e.g. in seconds) in the constructor.
Ruckig<6> ruckig {0.001}; // Number DoFs; control cycle in [s]
The input type has 3 blocks of data: the current state, the target state and the corresponding kinematic limits.
InputParameter<6> input; // Number DoFs
input.current_position = {0.2, ...};
input.current_velocity = {0.1, ...};
input.current_acceleration = {0.1, ...};
input.target_position = {0.5, ...};
input.target_velocity = {-0.1, ...};
input.target_acceleration = {0.2, ...};
input.max_velocity = {0.4, ...};
input.max_acceleration = {1.0, ...};
input.max_jerk = {4.0, ...};
OutputParameter<6> output; // Number DoFs
If you only want to have a acceleration-constrained trajectory, you can also omit the max_jerk
as well as the current
and target_acceleration
value. Given all input and output resources, we can iterate over the trajectory at each discrete time step. For most applications, this loop must run within a real-time thread and controls the actual hardware.
while (ruckig.update(input, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
output.pass_to_input(input); // Don't forget this!
}
Within the control loop, you need to update the current state of the input parameter according to the calculated trajectory. Therefore, the pass_to_input
method copies the new kinematic state of the output to the current kinematic state of the input parameter. If (in the next step) the current state is not the expected, pre-calculated trajectory, Ruckig will calculate a new trajectory based on the novel input. When the trajectory has reached the target state, the update
function will return Result::Finished
.
Intermediate Waypoints
The Ruckig Community Version now supports intermediate waypoints via a cloud API. To allocate the necessary memory for a variable number of waypoints beforehand, we need to pass the maximum number of waypoints to Ruckig via
Ruckig<6> otg {0.001, 8};
InputParameter<6> input {8};
OutputParameter<6> output {8};
The InputParameter
class takes the number of waypoints as an optional input, however usually you will fill in the values (and therefore reserve its memory) yourself. Then you’re ready to set intermediate via points by
input.intermediate_positions = {
{0.2, ...},
{0.8, ...},
};
As soon as at least one intermediate positions is given, the Ruckig Community Version switches to the mentioned (of course, non real-time capable) cloud API. If you require real-time calculation on your own hardware, please contact us for the Ruckig Pro Version.
When using intermediate positions, both the underlying motion planning problem as well as its calculation changes significantly. In particular, there are some fundamental limitations for jerk-limited online trajectory generation regarding the usage of waypoints. Please find more information about these limitations here, and in general we recommend to use
input.intermediate_positions = otg.filter_intermediate_positions(input.intermediate_positions, {0.1, ...});
to filter waypoints according to a (high) threshold distance. Setting interrupt_calculation_duration makes sure to be real-time capable by refining the solution in the next control invocation. Note that this is a soft interruption of the calculation. Currently, no minimum or discrete durations are supported when using intermediate positions.
Input Parameter
To go into more detail, the InputParameter type has following members:
using Vector = std::array<double, DOFs>; // By default
Vector current_position;
Vector current_velocity; // Initialized to zero
Vector current_acceleration; // Initialized to zero
std::vector<Vector> intermediate_positions; // (only in Pro Version)
Vector target_position;
Vector target_velocity; // Initialized to zero
Vector target_acceleration; // Initialized to zero
Vector max_velocity;
Vector max_acceleration;
Vector max_jerk; // Initialized to infinity
std::optional<Vector> min_velocity; // If not given, the negative maximum velocity will be used.
std::optional<Vector> min_acceleration; // If not given, the negative maximum acceleration will be used.
std::optional<Vector> min_position; // (only in Pro Version)
std::optional<Vector> max_position; // (only in Pro Version)
std::array<bool, DOFs> enabled; // Initialized to true
std::optional<double> minimum_duration;
std::optional<double> interrupt_calculation_duration; // [µs], (only in Pro Version)
ControlInterface control_interface; // The default position interface controls the full kinematic state.
Synchronization synchronization; // Synchronization behavior of multiple DoFs
DurationDiscretization duration_discretization; // Whether the duration should be a discrete multiple of the control cycle (off by default)
std::optional<Vector<ControlInterface>> per_dof_control_interface; // Sets the control interface for each DoF individually, overwrites global control_interface
std::optional<Vector<Synchronization>> per_dof_synchronization; // Sets the synchronization for each DoF individually, overwrites global synchronization
On top of the current state, target state, and constraints, Ruckig allows for a few more advanced settings:
- A minimum velocity and acceleration can be specified - these should be a negative number. If they are not given, the negative maximum velocity or acceleration will be used (similar to the jerk limit). For example, this might be useful in human robot collaboration settings with a different velocity limit towards a human. Or, when switching between different moving coordinate frames like picking from a conveyer belt.
- You can overwrite the global kinematic limits to specify limits for each section between two waypoints separately by using e.g.
per_section_max_velocity
. - If a DoF is not enabled, it will be ignored in the calculation. Ruckig will output a trajectory with constant acceleration for those DoFs.
- A minimum duration can be optionally given. Note that Ruckig can not guarantee an exact, but only a minimum duration of the trajectory.
- The control interface (position or velocity control) can be switched easily. For example, a stop trajectory or visual servoing can be easily implemented with the velocity interface.
- Different synchronization behaviors (i.a. phase, time, or no synchonization) are implemented. Phase synchronization results in straight-line motions.
- The trajectory duration might be constrained to a multiple of the control cycle. This way, the exact state can be reached at a control loop execution.
We refer to the API documentation of the enumerations within the ruckig
namespace for all available options.
Input Validation
To check that Ruckig is able to generate a trajectory before the actual calculation step,
ruckig.validate_input(input, check_current_state_within_limits=false, check_target_state_within_limits=true);
// returns true or throws
throws an error with a detailed reason if an input is not valid. You can also set the default template parameter to false via ruckig.validate_input<false>(...)
to just return a boolean true or false. The two boolean arguments check that the current or target state are within the limits. The check includes a typical catch of jerk-limited trajectory generation: When the current state is at maximal velocity, any positive acceleration will inevitable lead to a velocity violation at a future timestep. In general, this condition is fulfilled when
Abs(acceleration) <= Sqrt(2 * max_jerk * (max_velocity - Abs(velocity))).
If both arguments are set to true, the calculated trajectory is guaranteed to be within the kinematic limits throughout its duration. Also, note that there are range constraints of the input due to numerical reasons, see below for more details.
Result Type
The update
function of the Ruckig class returns a Result type that indicates the current state of the algorithm. This can either be working, finished if the trajectory has finished, or an error type if something went wrong during calculation. The result type can be compared as a standard integer.
State | Error Code |
---|---|
Working | 0 |
Finished | 1 |
Error | -1 |
ErrorInvalidInput | -100 |
ErrorTrajectoryDuration | -101 |
ErrorPositionalLimits | -102 |
ErrorExecutionTimeCalculation | -110 |
ErrorSynchronizationCalculation | -111 |
Output Parameter
The output class includes the new kinematic state and the overall trajectory.
Vector new_position;
Vector new_velocity;
Vector new_acceleration;
Trajectory trajectory; // The current trajectory
double time; // The current, auto-incremented time. Reset to 0 at a new calculation.
size_t new_section; // Index of the section between two (possibly filtered) intermediate positions.
bool did_section_change; // Was a new section reached in the last cycle?
bool new_calculation; // Whether a new calculation was performed in the last cycle
bool was_calculation_interrupted; // Was the trajectory calculation interrupted? (only in Pro Version)
double calculation_duration; // Duration of the calculation in the last cycle [µs]
Moreover, the trajectory class has a range of useful parameters and methods.
double duration; // Duration of the trajectory
std::array<double, DOFs> independent_min_durations; // Time-optimal profile for each independent DoF
<...> at_time(double time); // Get the kinematic state of the trajectory at a given time
<...> get_position_extrema(); // Returns information about the position extrema and their times
Again, we refer to the API documentation for the exact signatures.
Offline Calculation
Ruckig also supports an offline approach for calculating a trajectory:
result = ruckig.calculate(input, trajectory);
When only using this method, the Ruckig
constructor does not need a control cycle (delta_time
) as an argument. However if given, Ruckig supports stepping through the trajectory with
while (ruckig.update(trajectory, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
}
starting from the current output.time
(currently Ruckig Pro only).
Tracking Interface
When following an arbitrary signal with position, velocity, acceleration, and jerk-limitation, the straight forward way would be to pass the current state to Ruckig’s target state. However, as the resulting trajectory will take time to catch up, this approach will always lag behind the signal. The tracking interface solves this problem by predicting ahead (e.g. with constant acceleration by default) and is therefore able to follow signals very closely in a time-optimal way. This might be very helpful for (general) tracking, robot servoing, or trajectory post-processing applications.
To use the tracking interface, construct
Trackig<1> otg {0.01}; // control cycle
and set the current state as well as the kinematic constraints via
input.current_position = {0.0};
input.current_velocity = {0.0};
input.current_acceleration = {0.0};
input.max_velocity = {0.8};
input.max_acceleration = {2.0};
input.max_jerk = {5.0};
Then, we can track a signal in an online manner within the real-time control loop
for (double t = 0; t < 10.0; t += otg.delta_time) {
auto target_state = signal(t); // signal returns position, velocity, and acceleration
auto res = otg.update(target_state, input, output);
// Make use of the smooth target motion here (e.g. output.new_position)
output.pass_to_input(input);
}
Please find a complete example here. This functionality can also be used in an offline manner, e.g. when the entire signal is known beforehand. Here, we call the
smooth_trajectory = otg.calculate_trajectory(target_states, input);
method with the trajectory given as a std::vector
of target states. The Tracking interface is available in the Ruckig Pro version.
Dynamic Number of Degrees of Freedom
So far, we have told Ruckig the number of DoFs as a template parameter. If you don’t know the number of DoFs at compile-time, you can set the template parameter to ruckig::DynamicDOFs
and pass the DoFs to the constructor:
Ruckig<DynamicDOFs> otg {6, 0.001};
InputParameter<DynamicDOFs> input {6};
OutputParameter<DynamicDOFs> output {6};
This switches the default Vector from the std::array
to the dynamic std::vector
type. However, we recommend to keep the template parameter when possible: First, it has a performance benefit of a few percent. Second, it is convenient for real-time programming due to its easier handling of memory allocations. When using dynamic degrees of freedom, make sure to allocate the memory of all vectors beforehand.
Custom Vector Types
Ruckig supports custom vector types to make interfacing with your code even easier and more flexible. Most importantly, you can switch to Eigen Vectors simply by including Eigen (3.4 or later) before Ruckig
#include <Eigen/Core> // Version 3.4 or later
#include <ruckig/ruckig.hpp>
and then call the constructors with the ruckig::EigenVector
parameter.
Ruckig<6, EigenVector> otg {0.001};
InputParameter<6, EigenVector> input;
OutputParameter<6, EigenVector> output;
Now every in- and output of Ruckig’s API (such as current_position
, new_position
or max_jerk
) are Eigen types! To define completely custom vector types, you can pass a C++ template template parameter to the constructor. This template template parameter needs to fulfill a range of template arguments and methods:
template<class Type, size_t DOFs>
struct MinimalVector {
Type operator[](size_t i) const; // Array [] getter
Type& operator[](size_t i); // Array [] setter
size_t size() const; // Current size
bool operator==(const MinimalVector<T, DOFs>& rhs) const; // Equal comparison operator
// Only required in combination with DynamicDOFs, e.g. to allocate memory
void resize(size_t size);
};
Note that DynamicDOFs
corresponds to DOFs = 0
. We’ve included a range of examples for using Ruckig with (10) Eigen, (11) custom vector types, and (12) custom types with a dynamic number of DoFs.
Tests and Numerical Stability
The current test suite validates over 5.000.000.000 random trajectories as well as many additional edge cases. The numerical exactness is tested for the final position and final velocity to be within 1e-8
, for the final acceleration to be within 1e-10
, and for the velocity, acceleration and jerk limit to be within of a numerical error of 1e-12
. These are absolute values - we suggest to scale your input so that these correspond to your required precision of the system. For example, for most real-world systems we suggest to use input values in [m]
(instead of e.g. [mm]
), as 1e-8m
is sufficient precise for practical trajectory generation. Furthermore, all kinematic limits should be below 1e9
. The maximal supported trajectory duration is 7e3
. Note that Ruckig will also output values outside of this range, there is however no guarantee for correctness.
The Ruckig Pro version has additional tools to increase the numerical range and improve reliability. For example, theposition_scale
and time_scale
parameter of the Calculator
class change the internal representation of the input parameters.
Ruckig<1> otg;
// Works also for Trackig<1> otg;
otg.calculator.position_scale = 1e2; // Scales all positions in the input parameters
otg.calculator.time_scale = 1e3; // Scale all times in the input parameters
This way, you can easily achieve the requirements above even for very high jerk limits or very long trajectories. Note that the scale parameters don’t effect the resulting trajectory - they are for internal calculation only.
Benchmark
We find that Ruckig is more than twice as fast as Reflexxes Type IV for state-to-state motions and well-suited for control cycles as low as 250 microseconds. The Ruckig Community Version is in general a more powerful and open-source alternative to the Reflexxes Type IV library. In fact, Ruckig is the first Type V trajectory generator for arbitrary target states and even supports directional velocity and acceleration limits, while also being faster on top.
For trajectories with intermediate waypoints, we compare Ruckig to Toppra, a state-of-the-art library for robotic motion planning. Ruckig is able to improve the trajectory duration on average by around 10%, as the path planning and time parametrization are calculated jointly. Moreover, Ruckig is real-time capable and supports jerk-constraints.
Development
Ruckig is written in C++17. It is continuously tested on ubuntu-latest
, macos-latest
, and windows-latest
against following versions
- Doctest v2.4 (only for testing)
- Pybind11 v2.12 (only for Python wrapper)
A C++11 and C++03 version of Ruckig is also available - please contact us if you’re interested.
Used By
Ruckig is used by over hundred research labs, companies, and open-source projects worldwide, including:
- MoveIt 2 for trajectory generation.
- CoppeliaSim starting from version 4.3.
- Fuzzy Logic Robotics
- Gestalt Robotics
- Struckig, a port of Ruckig to Structered Text (ST - IEC61131-3) for usage on PLCs.
- Scanlab for controlling lasers.
- Frankx for controlling the Franka Emika robot arm.
- Wiredworks made a simple Kivy GUI application
- and many others!
Citation
@article{berscheid2021jerk,
title={Jerk-limited Real-time Trajectory Generation with Arbitrary Target States},
author={Berscheid, Lars and Kr{\"o}ger, Torsten},
journal={Robotics: Science and Systems XVII},
year={2021}
}
Changelog for package ruckig
Forthcoming
- [ci] don't check python for c++11
- [ci] move gcc-5 to ubuntu 20.04
- bump version
- add example for per section minimum duration
- Budan's theorem
- use valid profile iterator in step1
- add jerk-minimizing profiles in step2
- fix c++11 patch
- fix c++11 patch
- fix patch c++11
- c++11 fix inplace patching
- improve support for c++11
- update pybind11 in ci
- fix optional in tests with c++11 patch
- update ci checkout version
- fix msvc warning in online calculator
- fix msvc compiler warnings
- expose calculators
- bump version
- performance improvement in step2 vel
- Contributors: pantor
0.8.4 (2022-09-13)
- robustify step2 vel uddu
- fix readme tracking example
- add tracking interface to readme
- fix brake duration reset
- fix brake when current acceleration is on limit
- improve tracking example
- fix pyproject.toml
- clean tracking example
- clean examples
- add pyproject file
- add DOFs to traj serialization
- nlohmann/json based serialization for trajectory
- point out Eigen 3.4 or later
- add custom vector types to readme
- disable vector types example with online client
- include deque
- add examples for custom vector types
- dont support custom data types with online client
- add tests and fixes for custom vector type
- use template specalization without using
- custom vector type as template template parameter
- clean error_at_max_duration, add StandardVector
- clean licenses
- update header dependencies
- clean comparison benchmarks
- extend phase synchronization to velocity control
- move src to src/ruckig
- clean gitignore
- remove -Werror
- Contributors: pantor
0.7.1 (2022-07-10)
- bump to 0.7.1
- fix python 3.10 deployment
- Merge branch 'master' of github.com:pantor/ruckig
- bump to 0.7.0
-
allow user to force new computation for the same input (#132) * allow user to force computation again Otherwise sending the same target with non-zero min_duration multiple times in a control loop will not trigger a new trajectory. * rename to reset Co-authored-by: pantor <<lars.berscheid@online.de>>
- profile precision as constant
- clean notebooks
- fix c++11 std::clamp
- use steady_clock, minor code cleaning of roots.hpp
- fix numeric for time sync with discrete durations
- fix independent min duration with brake trajectory
- clean header includes
- improve stability of velocity control
- msvc warnings
- fix msvc warnings
- static cast for std::div
- Merge branch 'master' of github.com:pantor/ruckig
- fix warnings, limiting_dof to std::optional
- doc: fixed used-by entry (#131)
- move roots into ruckig namespace
- refactor tests and benchmarks
- step2 vel catch root at boundary
- update benchmark plot
- add algorithm header, use c++ array
- make delta_time non const
- add smoothing of non-limiting dofs
- const degrees_of_freedom
- print error messages from online api
- check that current_input is initialized
- Contributors: Matthias Seehauser, Michael Görner, pantor
0.6.5 (2022-03-06)
- revert to manylinux2010_x86_64
- bump to v0.6.5
- fix pypi build from source
- remove 9_trajectory.png
- use .pdf for example trajectories
- numerical stability in velocity control
- fix for zero-to-zero traj with velocity control
- invalidate discrete duration
- fix numerical instability in acc0
- update to nlohmann/json v3.10.5
- bump to 0.6.4
- clarify Online API in examples and Readme
- fix example docs
- fix ci
- build waypoints example only for online client
- add joint example for dynamic dofs and waypoints
- fix capacity / actual waypoints mismatch
- disable ros cd
- retry
- retry
- retry
- debug publish ros
- Contributors: pantor
0.6.3 (2022-01-21)
- bump to v0.6.3
- activaten open_pr for bloom release
- publish ros on release
- test bloom ci
- add bloom release
- several perf optimizations, step2 stability
- clear up waypoints in readme
- fix time sync for discrete durations, rename step1
- Contributors: pantor
0.6.0 (2021-12-06)
- fix python upload
- bump version to 0.6.0
- filter_intermediate_positions
- add braces to if function
- fix error in step 2
- remove filter positions
- remote api for intermediate waypoints
- fix trajectories with zero duration
- use integrated instead target values after traj
- use back() instead of explicit number
- ci build matrix
- BUILD_ONLINE_CLIENT in python package
- add brake in online calculator
- fix ci online-calculator
- auto ci name
- add online calculator for intermediate waypoints
- add httplib and build option
- create third_party directory
- update demo notebook
- update notebook demo
- add jupyter demo notebook
- change brief description of calculator
- expose internal
- add note to ruckig pro examples
- clear up section term
- clean brake class
- refactor integrate to utils
- prepare accel phase
- use dynamic dofs const
- improve input validation
- clean up CD
- Contributors: pantor
0.5.0 (2021-11-14)
- debug publish
- publish pypi package on released release
- bump version
- add hint for Step 1 None
- optimize block class
- improve readme
- per_section_limits in readme
- add per_section_limits
- fix c+11 patch
- fix per dof synchronization
- split CMakeLists examples
- fix per dof synchronization with none
- separate trajectory and calculator class
- fix windows build
- code cleaning
- intermediate waypoints readme
- fix number of waypoints
- avoid pow completely
- update maintainer
- simplify readme
- use brake profile class
- fix finished trajectory for disabled dofs
- minor code cleaning
- Merge branch 'master' of github.com:pantor/ruckig
- add to_string for output parameters (#77)
- add ref to vel add_profile
- positional limits
- min limits for intermediate positions
- extend phase synchronization
- performance improvements
- add section to output in readme
- pass_to_input, did_section_change
- fix nullopt with c++11 patch
- fix nullopt in c++11 patch
- fix c++11
- per dof control interface and synchronization #53
- add section index to output
- Notes about Intermediate Waypoints
- interrupt calculation duration in microseconds
- add ruckig pro examples
- add ruckig toppra comparison
- improve readme and examples
- introduce Ruckig Pro
- remove generate docs ci
- link docs to ruckig.com
- add examples doc pages
- fix example names
- add more examples
- Instantaneous Motion Generation
- add calculation interruption
- add doxyfile again
- step1: numeric stability
- Contributors: Lars Berscheid, lpdon, pantor
0.4.0 (2021-08-23)
- update version to 0.4
- code cleaning
- add was_calculation_interrupted
- step 1: performance optimizations
- interrupt_calculation_duration
- Add CITATION.cff file
(#63)
- add CITATION.cff
- CITATOION wip
- fix cite
- Update README.md
- update to doctest 2.4.6
- code cleaning
- performance optimizations
- step 2: performance optimization
- step 2: performance optimization
- performance optimization: step 1
- performance optimization: positive set of roots
- performance optimization in step1
- code cleaning
- set find_package reflexxes to quiet
- remove BSD license text, why was it there anyway?
- clean plot trajectory
- add printing intermediate_positions
- code cleaning
- add degrees_of_freedom to python trajectory
- rename interface to control_interface
- set_limits for ACC1, code cleaning
- improve numeric stability
- in vel interface, change acc threshold
- code cleanup
- add DynamicDOFs constant
- numerical stability of velocity interface
- improve numerical stability
- fix variable name redeclaration
- fix jerk violation in step2, some optimizations
- clean up check methods of profile
- fix min_velocity with phas e synchronization
- fix phase synchronization in python
- improve numerical stability for high jerks
- fix newton step in acc0/acc1 for t=0
- clean up plot_trajectory
- validate for isnan
- fix python path in examples
- fix position extrema for dynamic number of dofs
- Added python example for non-realtime context
(#43)
- added python example for non-realtime context
- fixed ci workflow
- need to reset t_start
- rename
* change example Co-authored-by: Max Dhom <<md@adva.store>> Co-authored-by: Lars Berscheid <<lars.berscheid@kit.edu>>
- Dynamic Dofs (#47)
- vectorize
- use vector for dof==0
- add tests and checks
- include vector
- default dofs = 0, fix reflexxes
- redo default dofs template parameter
- add readme
- improve readme
- fix grammar
- add tests for invalid input
- add offline trajectory generation
- add paren to get time at position
- add get_first_time_at_position method
- Contributors: Lars Berscheid, Mathis, Max Dhom, pantor
0.3.3 (2021-06-25)
- Merge branch 'master' of github.com:pantor/ruckig
- version 0.3.3
- Set CMAKE_OUTPUT_DIRECTORY for windows build
(#41)
- check windows
- add library
- add debug log
- try to fix
- try to fix2
- try to fix 3
- try to fix 4
- fix 5
- rest test number
- fix setup.py
- remove log
- hard-code build directory of python library
- fix windows packge, version 0.3.2
- pre-compiled packages for windows on pypi
- Contributors: Lars Berscheid, pantor
0.3.1 (2021-06-24)
- set version 0.3.1
- add manifest.in
- double newton step in step2 vel udud
- Fix windows python package
(#38)
- fix windows
- update benchmark figure
- c++11 dont treat warnings as errors
- fix three step
- performance improvements
- vectorize dof
- Fix Patch for C++11
(#36)
- add ci for c++11
- remove maybe_unused
- patch in-place
- fix c++11
- replace make_unique
- find error in ci
- try to fix gcc-5
- dont build python
- dont patch cpp files
- deactivate cmake flags in patch script
- test python example
- add C++11 patch in readme
- add patch script for C++11
- Contributors: Lars Berscheid, pantor
0.3.0 (2021-06-16)
- update version number
- add python at_time comment for doxygen
- check for v_min, fix directional tests
- python return at_time method
- fix max target acceleration
- fix and test extremal positions
- synchronize function to trajectory class
- fix max target acceleration when min_velocity
- clean up docs
- fixed bug in check_position_extremum
(#33)
- fixed copy & paste error in Trajectory::is_phase_synchronizable
- fixed obvious copy & paste error in check_position_extremum
- fixed copy & paste error in Trajectory::is_phase_synchronizable (#32)
- fix negative, near zero pd cases
- Update README.md
- Update README.md
- Update README.md
- check limits with equal sign for numeric stability
- copy jerk_signs for phase synchronization
- remove alternative otgs
- add citation and link to paper
- remove alternative otgs from python
- fix numerical issues on time-optimal traj
- Merge branch 'master' of github.com:pantor/ruckig
- fix numeric error for long durations
- Scale to 5e9 random trajectories
- fix numerical issues
- add step through tests
- fix for braking
- double newton step
- fix macos and windows build
- recalculate after error
- fix some numerical issues
- use checkout@v2 in ci
- use ARCHIVE_OUTPUT_NAME for python wrapper
- msvc: warning as errors
- fix msvc compiler warnings
- Update README.md
- Update README.md
- Fix BUILD_PYTHON_MODULE option on Windows/MSVC (#18)
- fix ci args
- add phase synchronization
- set boundary method
- simplify python example
- Add pip install to Readme
- Contributors: Lars Berscheid, Silvio Traversaro, pantor, stefanbesler
0.2.6 (2021-03-29)
- remove env
- fix python cd
- use static library
- test python executable
- fix python package
- python cd: fix windows
- add setup.py, version 0.2.1
- rename python module to ruckig
- generate python classes for multiple dof
- Add a ROS package manifest (#10) Enables building Ruckig as a plain CMake package in a Catkin/Colcon workspace.
- fix end of brake trajectory integration
- Include GNU install dirs earlier (#11) Otherwise 'CMAKE_INSTALL_INCLUDEDIR' is empty/undefined when it's used to setup ruckig::ruckig's target_include_directories(..).
- readme: some minor typos (#9) I happened to notice them.
- privatize trajectory class members
- privatize some class members
- use cmath
- code cleaning
- show enum in docs
- split parameter files, calculate in trajectory
- code cleaning
- add python example
- Move options to API documentation
- Fix Readme Code
- fix undefined output for zero duration
- indicate default values in Readme
- add discrete durations
- Add Windows and macOS build to CI
(#4)
- windows and mac ci
- use cmake action for generator
- fix ci build directory
- run tests only on linux
- test example
- Add support to compile on Windows (#3)
- Merge pull request #2 from traversaro/patch-1 Use BUILD_SHARED_LIBS to select if compile C++ library as static or shared
- document examples/CMakeLists.txt
- add ci to PRs
- Use BUILD_SHARED_LIBS to select if compile as static or shared
- Merge pull request #1 from traversaro/add-install-support Add support for installation of the C++ library
- Add support for installation of the C++ library
- set correct cmake and doxygen version
- fix more edge cases
- fix some edge cases
- document velocity interface
- added velocity interface
- improve readme
- improve benchmark
- fix finding subdirectory
- check ci
- build python module in ci
- use own set class on stack
- fix synchronization enum, better python support
- add time synchronization parameter
- fix motion finished reset
- fix immediate reaction
- fix more edge cases
- refine min acceleration
- add min_acceleration
- fix some edge cases
- Merge branch 'master' of github.com:pantor/ruckig
- decrease required cmake to 3.10
- fix ci
- introduce trajectory class
- position extrema
- scale tests to 1e9
- several optimizations
- compile with warnings
- step2: code cleaning
- fix numeric edge cases
- move test suite to doctest
- fix cmake as submodule
- Merge branch 'master' of github.com:pantor/ruckig
- fix optional minimum time
- code documentation, more tests
- fix benchmark
- build benchmark in ci
- fix gcc
- remove eigen dep in cmake
- code cleaning
- code cleaning
- add comparison with multiple DoF
- rix ci: braking
- fix interval selection
- clean braking
- fix ci, more tests
- add benchmark, numeric stability
- fix block in step1
- clean root finding
- Increase stability
- improve tests, remove eigen
- code style
- increase test coverage
- add min_velocity
- fix ci
- Step1: Use Newton step
- fix ci
- fix time sync
- update tests
- more tests
- add example
- more tests
- increase number of tests
- simplify equations
- simplify equations
- simplify equations
- add tuple header
- further code cleaning
- remove eigen dependency, code cleaning
- clean brake code
- code cleaning
- code cleaning
- add doxygen
- improve acceleration target, readme
- refine max time deviation to 1e-8
- code cleaning
- improve time sync
- block synchronization
- stability for target acceleration in 1 dof
- update readme for ruckig
- add license
- improve tests
- fix eigen ci folder name
- fix eigen git repository
- fix 1dof vf comparison
- remove complex algorithmic
- code cleaning
- initial commit
- Contributors: G.A. vd. Hoorn, Lars Berscheid, Silvio Traversaro, pantor
Wiki Tutorials
Dependant Packages
Name | Deps |
---|---|
moveit_core |
Launch files
Messages
Services
Plugins
Recent questions tagged ruckig at Robotics Stack Exchange
Package Summary
Tags | No category tags. |
Version | 0.14.0 |
License | MIT |
Build type | CMAKE |
Use | RECOMMENDED |
Repository Summary
Checkout URI | https://github.com/pantor/ruckig.git |
VCS Type | git |
VCS Version | main |
Last Updated | 2024-12-08 |
Dev Status | DEVELOPED |
CI status | No Continuous Integration |
Released | RELEASED |
Tags | No category tags. |
Contributing |
Help Wanted (0)
Good First Issues (0) Pull Requests to Review (0) |
Package Description
Additional Links
Maintainers
- Lars Berscheid
Authors
- Lars Berscheid
Ruckig
Instantaneous Motion Generation for Robots and Machines.
Ruckig generates trajectories on-the-fly, allowing robots and machines to react instantaneously to sensor input. Ruckig calculates a trajectory to a target waypoint (with position, velocity, and acceleration) starting from any initial state limited by velocity, acceleration, and jerk constraints. Besides the target state, Ruckig allows to define intermediate positions for waypoint following. For state-to-state motions, Ruckig guarantees a time-optimal solution. With intermediate waypoints, Ruckig calculates the path and its time parametrization jointly, resulting in significantly faster trajectories compared to traditional methods.
More information can be found at ruckig.com and in the corresponding paper Jerk-limited Real-time Trajectory Generation with Arbitrary Target States, accepted for the Robotics: Science and Systems (RSS), 2021 conference.
Installation
Ruckig has no dependencies (except for testing). To build Ruckig using CMake, just run
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
To install Ruckig in a system-wide directory, you can either use (sudo) make install
or install it as debian package using cpack by running
cpack
sudo dpkg -i ruckig*.deb
An example of using Ruckig in your CMake project is given by examples/CMakeLists.txt
. However, you can also include Ruckig as a directory within your project and call add_subdirectory(ruckig)
in your parent CMakeLists.txt
.
Ruckig is also available as a Python module, in particular for development or debugging purposes. The Ruckig Community Version can be installed from PyPI via
pip install ruckig
When using CMake, the Python module can be built using the BUILD_PYTHON_MODULE
flag. If you’re only interested in the Python module (and not in the C++ library), you can build and install Ruckig via pip install .
.
Tutorial
Furthermore, we will explain the basics to get started with online generated trajectories within your application. There is also a collection of examples that guide you through the most important features of Ruckig. A time-optimal trajectory for a single degree of freedom is shown in the figure below. We also added plots of the resulting trajectories for all examples. Let’s get started!
Waypoint-based Trajectory Generation
Ruckig provides three main interface classes: the Ruckig, the InputParameter, and the OutputParameter class.
First, you’ll need to create a Ruckig instance with the number of DoFs as a template parameter, and the control cycle (e.g. in seconds) in the constructor.
Ruckig<6> ruckig {0.001}; // Number DoFs; control cycle in [s]
The input type has 3 blocks of data: the current state, the target state and the corresponding kinematic limits.
InputParameter<6> input; // Number DoFs
input.current_position = {0.2, ...};
input.current_velocity = {0.1, ...};
input.current_acceleration = {0.1, ...};
input.target_position = {0.5, ...};
input.target_velocity = {-0.1, ...};
input.target_acceleration = {0.2, ...};
input.max_velocity = {0.4, ...};
input.max_acceleration = {1.0, ...};
input.max_jerk = {4.0, ...};
OutputParameter<6> output; // Number DoFs
If you only want to have a acceleration-constrained trajectory, you can also omit the max_jerk
as well as the current
and target_acceleration
value. Given all input and output resources, we can iterate over the trajectory at each discrete time step. For most applications, this loop must run within a real-time thread and controls the actual hardware.
while (ruckig.update(input, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
output.pass_to_input(input); // Don't forget this!
}
Within the control loop, you need to update the current state of the input parameter according to the calculated trajectory. Therefore, the pass_to_input
method copies the new kinematic state of the output to the current kinematic state of the input parameter. If (in the next step) the current state is not the expected, pre-calculated trajectory, Ruckig will calculate a new trajectory based on the novel input. When the trajectory has reached the target state, the update
function will return Result::Finished
.
Intermediate Waypoints
The Ruckig Community Version now supports intermediate waypoints via a cloud API. To allocate the necessary memory for a variable number of waypoints beforehand, we need to pass the maximum number of waypoints to Ruckig via
Ruckig<6> otg {0.001, 8};
InputParameter<6> input {8};
OutputParameter<6> output {8};
The InputParameter
class takes the number of waypoints as an optional input, however usually you will fill in the values (and therefore reserve its memory) yourself. Then you’re ready to set intermediate via points by
input.intermediate_positions = {
{0.2, ...},
{0.8, ...},
};
As soon as at least one intermediate positions is given, the Ruckig Community Version switches to the mentioned (of course, non real-time capable) cloud API. If you require real-time calculation on your own hardware, please contact us for the Ruckig Pro Version.
When using intermediate positions, both the underlying motion planning problem as well as its calculation changes significantly. In particular, there are some fundamental limitations for jerk-limited online trajectory generation regarding the usage of waypoints. Please find more information about these limitations here, and in general we recommend to use
input.intermediate_positions = otg.filter_intermediate_positions(input.intermediate_positions, {0.1, ...});
to filter waypoints according to a (high) threshold distance. Setting interrupt_calculation_duration makes sure to be real-time capable by refining the solution in the next control invocation. Note that this is a soft interruption of the calculation. Currently, no minimum or discrete durations are supported when using intermediate positions.
Input Parameter
To go into more detail, the InputParameter type has following members:
using Vector = std::array<double, DOFs>; // By default
Vector current_position;
Vector current_velocity; // Initialized to zero
Vector current_acceleration; // Initialized to zero
std::vector<Vector> intermediate_positions; // (only in Pro Version)
Vector target_position;
Vector target_velocity; // Initialized to zero
Vector target_acceleration; // Initialized to zero
Vector max_velocity;
Vector max_acceleration;
Vector max_jerk; // Initialized to infinity
std::optional<Vector> min_velocity; // If not given, the negative maximum velocity will be used.
std::optional<Vector> min_acceleration; // If not given, the negative maximum acceleration will be used.
std::optional<Vector> min_position; // (only in Pro Version)
std::optional<Vector> max_position; // (only in Pro Version)
std::array<bool, DOFs> enabled; // Initialized to true
std::optional<double> minimum_duration;
std::optional<double> interrupt_calculation_duration; // [µs], (only in Pro Version)
ControlInterface control_interface; // The default position interface controls the full kinematic state.
Synchronization synchronization; // Synchronization behavior of multiple DoFs
DurationDiscretization duration_discretization; // Whether the duration should be a discrete multiple of the control cycle (off by default)
std::optional<Vector<ControlInterface>> per_dof_control_interface; // Sets the control interface for each DoF individually, overwrites global control_interface
std::optional<Vector<Synchronization>> per_dof_synchronization; // Sets the synchronization for each DoF individually, overwrites global synchronization
On top of the current state, target state, and constraints, Ruckig allows for a few more advanced settings:
- A minimum velocity and acceleration can be specified - these should be a negative number. If they are not given, the negative maximum velocity or acceleration will be used (similar to the jerk limit). For example, this might be useful in human robot collaboration settings with a different velocity limit towards a human. Or, when switching between different moving coordinate frames like picking from a conveyer belt.
- You can overwrite the global kinematic limits to specify limits for each section between two waypoints separately by using e.g.
per_section_max_velocity
. - If a DoF is not enabled, it will be ignored in the calculation. Ruckig will output a trajectory with constant acceleration for those DoFs.
- A minimum duration can be optionally given. Note that Ruckig can not guarantee an exact, but only a minimum duration of the trajectory.
- The control interface (position or velocity control) can be switched easily. For example, a stop trajectory or visual servoing can be easily implemented with the velocity interface.
- Different synchronization behaviors (i.a. phase, time, or no synchonization) are implemented. Phase synchronization results in straight-line motions.
- The trajectory duration might be constrained to a multiple of the control cycle. This way, the exact state can be reached at a control loop execution.
We refer to the API documentation of the enumerations within the ruckig
namespace for all available options.
Input Validation
To check that Ruckig is able to generate a trajectory before the actual calculation step,
ruckig.validate_input(input, check_current_state_within_limits=false, check_target_state_within_limits=true);
// returns true or throws
throws an error with a detailed reason if an input is not valid. You can also set the default template parameter to false via ruckig.validate_input<false>(...)
to just return a boolean true or false. The two boolean arguments check that the current or target state are within the limits. The check includes a typical catch of jerk-limited trajectory generation: When the current state is at maximal velocity, any positive acceleration will inevitable lead to a velocity violation at a future timestep. In general, this condition is fulfilled when
Abs(acceleration) <= Sqrt(2 * max_jerk * (max_velocity - Abs(velocity))).
If both arguments are set to true, the calculated trajectory is guaranteed to be within the kinematic limits throughout its duration. Also, note that there are range constraints of the input due to numerical reasons, see below for more details.
Result Type
The update
function of the Ruckig class returns a Result type that indicates the current state of the algorithm. This can either be working, finished if the trajectory has finished, or an error type if something went wrong during calculation. The result type can be compared as a standard integer.
State | Error Code |
---|---|
Working | 0 |
Finished | 1 |
Error | -1 |
ErrorInvalidInput | -100 |
ErrorTrajectoryDuration | -101 |
ErrorPositionalLimits | -102 |
ErrorExecutionTimeCalculation | -110 |
ErrorSynchronizationCalculation | -111 |
Output Parameter
The output class includes the new kinematic state and the overall trajectory.
Vector new_position;
Vector new_velocity;
Vector new_acceleration;
Trajectory trajectory; // The current trajectory
double time; // The current, auto-incremented time. Reset to 0 at a new calculation.
size_t new_section; // Index of the section between two (possibly filtered) intermediate positions.
bool did_section_change; // Was a new section reached in the last cycle?
bool new_calculation; // Whether a new calculation was performed in the last cycle
bool was_calculation_interrupted; // Was the trajectory calculation interrupted? (only in Pro Version)
double calculation_duration; // Duration of the calculation in the last cycle [µs]
Moreover, the trajectory class has a range of useful parameters and methods.
double duration; // Duration of the trajectory
std::array<double, DOFs> independent_min_durations; // Time-optimal profile for each independent DoF
<...> at_time(double time); // Get the kinematic state of the trajectory at a given time
<...> get_position_extrema(); // Returns information about the position extrema and their times
Again, we refer to the API documentation for the exact signatures.
Offline Calculation
Ruckig also supports an offline approach for calculating a trajectory:
result = ruckig.calculate(input, trajectory);
When only using this method, the Ruckig
constructor does not need a control cycle (delta_time
) as an argument. However if given, Ruckig supports stepping through the trajectory with
while (ruckig.update(trajectory, output) == Result::Working) {
// Make use of the new state here!
// e.g. robot->setJointPositions(output.new_position);
}
starting from the current output.time
(currently Ruckig Pro only).
Tracking Interface
When following an arbitrary signal with position, velocity, acceleration, and jerk-limitation, the straight forward way would be to pass the current state to Ruckig’s target state. However, as the resulting trajectory will take time to catch up, this approach will always lag behind the signal. The tracking interface solves this problem by predicting ahead (e.g. with constant acceleration by default) and is therefore able to follow signals very closely in a time-optimal way. This might be very helpful for (general) tracking, robot servoing, or trajectory post-processing applications.
To use the tracking interface, construct
Trackig<1> otg {0.01}; // control cycle
and set the current state as well as the kinematic constraints via
input.current_position = {0.0};
input.current_velocity = {0.0};
input.current_acceleration = {0.0};
input.max_velocity = {0.8};
input.max_acceleration = {2.0};
input.max_jerk = {5.0};
Then, we can track a signal in an online manner within the real-time control loop
for (double t = 0; t < 10.0; t += otg.delta_time) {
auto target_state = signal(t); // signal returns position, velocity, and acceleration
auto res = otg.update(target_state, input, output);
// Make use of the smooth target motion here (e.g. output.new_position)
output.pass_to_input(input);
}
Please find a complete example here. This functionality can also be used in an offline manner, e.g. when the entire signal is known beforehand. Here, we call the
smooth_trajectory = otg.calculate_trajectory(target_states, input);
method with the trajectory given as a std::vector
of target states. The Tracking interface is available in the Ruckig Pro version.
Dynamic Number of Degrees of Freedom
So far, we have told Ruckig the number of DoFs as a template parameter. If you don’t know the number of DoFs at compile-time, you can set the template parameter to ruckig::DynamicDOFs
and pass the DoFs to the constructor:
Ruckig<DynamicDOFs> otg {6, 0.001};
InputParameter<DynamicDOFs> input {6};
OutputParameter<DynamicDOFs> output {6};
This switches the default Vector from the std::array
to the dynamic std::vector
type. However, we recommend to keep the template parameter when possible: First, it has a performance benefit of a few percent. Second, it is convenient for real-time programming due to its easier handling of memory allocations. When using dynamic degrees of freedom, make sure to allocate the memory of all vectors beforehand.
Custom Vector Types
Ruckig supports custom vector types to make interfacing with your code even easier and more flexible. Most importantly, you can switch to Eigen Vectors simply by including Eigen (3.4 or later) before Ruckig
#include <Eigen/Core> // Version 3.4 or later
#include <ruckig/ruckig.hpp>
and then call the constructors with the ruckig::EigenVector
parameter.
Ruckig<6, EigenVector> otg {0.001};
InputParameter<6, EigenVector> input;
OutputParameter<6, EigenVector> output;
Now every in- and output of Ruckig’s API (such as current_position
, new_position
or max_jerk
) are Eigen types! To define completely custom vector types, you can pass a C++ template template parameter to the constructor. This template template parameter needs to fulfill a range of template arguments and methods:
template<class Type, size_t DOFs>
struct MinimalVector {
Type operator[](size_t i) const; // Array [] getter
Type& operator[](size_t i); // Array [] setter
size_t size() const; // Current size
bool operator==(const MinimalVector<T, DOFs>& rhs) const; // Equal comparison operator
// Only required in combination with DynamicDOFs, e.g. to allocate memory
void resize(size_t size);
};
Note that DynamicDOFs
corresponds to DOFs = 0
. We’ve included a range of examples for using Ruckig with (10) Eigen, (11) custom vector types, and (12) custom types with a dynamic number of DoFs.
Tests and Numerical Stability
The current test suite validates over 5.000.000.000 random trajectories as well as many additional edge cases. The numerical exactness is tested for the final position and final velocity to be within 1e-8
, for the final acceleration to be within 1e-10
, and for the velocity, acceleration and jerk limit to be within of a numerical error of 1e-12
. These are absolute values - we suggest to scale your input so that these correspond to your required precision of the system. For example, for most real-world systems we suggest to use input values in [m]
(instead of e.g. [mm]
), as 1e-8m
is sufficient precise for practical trajectory generation. Furthermore, all kinematic limits should be below 1e9
. The maximal supported trajectory duration is 7e3
. Note that Ruckig will also output values outside of this range, there is however no guarantee for correctness.
The Ruckig Pro version has additional tools to increase the numerical range and improve reliability. For example, theposition_scale
and time_scale
parameter of the Calculator
class change the internal representation of the input parameters.
Ruckig<1> otg;
// Works also for Trackig<1> otg;
otg.calculator.position_scale = 1e2; // Scales all positions in the input parameters
otg.calculator.time_scale = 1e3; // Scale all times in the input parameters
This way, you can easily achieve the requirements above even for very high jerk limits or very long trajectories. Note that the scale parameters don’t effect the resulting trajectory - they are for internal calculation only.
Benchmark
We find that Ruckig is more than twice as fast as Reflexxes Type IV for state-to-state motions and well-suited for control cycles as low as 250 microseconds. The Ruckig Community Version is in general a more powerful and open-source alternative to the Reflexxes Type IV library. In fact, Ruckig is the first Type V trajectory generator for arbitrary target states and even supports directional velocity and acceleration limits, while also being faster on top.
For trajectories with intermediate waypoints, we compare Ruckig to Toppra, a state-of-the-art library for robotic motion planning. Ruckig is able to improve the trajectory duration on average by around 10%, as the path planning and time parametrization are calculated jointly. Moreover, Ruckig is real-time capable and supports jerk-constraints.
Development
Ruckig is written in C++17. It is continuously tested on ubuntu-latest
, macos-latest
, and windows-latest
against following versions
- Doctest v2.4 (only for testing)
- Pybind11 v2.12 (only for Python wrapper)
A C++11 and C++03 version of Ruckig is also available - please contact us if you’re interested.
Used By
Ruckig is used by over hundred research labs, companies, and open-source projects worldwide, including:
- MoveIt 2 for trajectory generation.
- CoppeliaSim starting from version 4.3.
- Fuzzy Logic Robotics
- Gestalt Robotics
- Struckig, a port of Ruckig to Structered Text (ST - IEC61131-3) for usage on PLCs.
- Scanlab for controlling lasers.
- Frankx for controlling the Franka Emika robot arm.
- Wiredworks made a simple Kivy GUI application
- and many others!
Citation
@article{berscheid2021jerk,
title={Jerk-limited Real-time Trajectory Generation with Arbitrary Target States},
author={Berscheid, Lars and Kr{\"o}ger, Torsten},
journal={Robotics: Science and Systems XVII},
year={2021}
}
Changelog for package ruckig
Forthcoming
- [ci] don't check python for c++11
- [ci] move gcc-5 to ubuntu 20.04
- bump version
- add example for per section minimum duration
- Budan's theorem
- use valid profile iterator in step1
- add jerk-minimizing profiles in step2
- fix c++11 patch
- fix c++11 patch
- fix patch c++11
- c++11 fix inplace patching
- improve support for c++11
- update pybind11 in ci
- fix optional in tests with c++11 patch
- update ci checkout version
- fix msvc warning in online calculator
- fix msvc compiler warnings
- expose calculators
- bump version
- performance improvement in step2 vel
- Contributors: pantor
0.8.4 (2022-09-13)
- robustify step2 vel uddu
- fix readme tracking example
- add tracking interface to readme
- fix brake duration reset
- fix brake when current acceleration is on limit
- improve tracking example
- fix pyproject.toml
- clean tracking example
- clean examples
- add pyproject file
- add DOFs to traj serialization
- nlohmann/json based serialization for trajectory
- point out Eigen 3.4 or later
- add custom vector types to readme
- disable vector types example with online client
- include deque
- add examples for custom vector types
- dont support custom data types with online client
- add tests and fixes for custom vector type
- use template specalization without using
- custom vector type as template template parameter
- clean error_at_max_duration, add StandardVector
- clean licenses
- update header dependencies
- clean comparison benchmarks
- extend phase synchronization to velocity control
- move src to src/ruckig
- clean gitignore
- remove -Werror
- Contributors: pantor
0.7.1 (2022-07-10)
- bump to 0.7.1
- fix python 3.10 deployment
- Merge branch 'master' of github.com:pantor/ruckig
- bump to 0.7.0
-
allow user to force new computation for the same input (#132) * allow user to force computation again Otherwise sending the same target with non-zero min_duration multiple times in a control loop will not trigger a new trajectory. * rename to reset Co-authored-by: pantor <<lars.berscheid@online.de>>
- profile precision as constant
- clean notebooks
- fix c++11 std::clamp
- use steady_clock, minor code cleaning of roots.hpp
- fix numeric for time sync with discrete durations
- fix independent min duration with brake trajectory
- clean header includes
- improve stability of velocity control
- msvc warnings
- fix msvc warnings
- static cast for std::div
- Merge branch 'master' of github.com:pantor/ruckig
- fix warnings, limiting_dof to std::optional
- doc: fixed used-by entry (#131)
- move roots into ruckig namespace
- refactor tests and benchmarks
- step2 vel catch root at boundary
- update benchmark plot
- add algorithm header, use c++ array
- make delta_time non const
- add smoothing of non-limiting dofs
- const degrees_of_freedom
- print error messages from online api
- check that current_input is initialized
- Contributors: Matthias Seehauser, Michael Görner, pantor
0.6.5 (2022-03-06)
- revert to manylinux2010_x86_64
- bump to v0.6.5
- fix pypi build from source
- remove 9_trajectory.png
- use .pdf for example trajectories
- numerical stability in velocity control
- fix for zero-to-zero traj with velocity control
- invalidate discrete duration
- fix numerical instability in acc0
- update to nlohmann/json v3.10.5
- bump to 0.6.4
- clarify Online API in examples and Readme
- fix example docs
- fix ci
- build waypoints example only for online client
- add joint example for dynamic dofs and waypoints
- fix capacity / actual waypoints mismatch
- disable ros cd
- retry
- retry
- retry
- debug publish ros
- Contributors: pantor
0.6.3 (2022-01-21)
- bump to v0.6.3
- activaten open_pr for bloom release
- publish ros on release
- test bloom ci
- add bloom release
- several perf optimizations, step2 stability
- clear up waypoints in readme
- fix time sync for discrete durations, rename step1
- Contributors: pantor
0.6.0 (2021-12-06)
- fix python upload
- bump version to 0.6.0
- filter_intermediate_positions
- add braces to if function
- fix error in step 2
- remove filter positions
- remote api for intermediate waypoints
- fix trajectories with zero duration
- use integrated instead target values after traj
- use back() instead of explicit number
- ci build matrix
- BUILD_ONLINE_CLIENT in python package
- add brake in online calculator
- fix ci online-calculator
- auto ci name
- add online calculator for intermediate waypoints
- add httplib and build option
- create third_party directory
- update demo notebook
- update notebook demo
- add jupyter demo notebook
- change brief description of calculator
- expose internal
- add note to ruckig pro examples
- clear up section term
- clean brake class
- refactor integrate to utils
- prepare accel phase
- use dynamic dofs const
- improve input validation
- clean up CD
- Contributors: pantor
0.5.0 (2021-11-14)
- debug publish
- publish pypi package on released release
- bump version
- add hint for Step 1 None
- optimize block class
- improve readme
- per_section_limits in readme
- add per_section_limits
- fix c+11 patch
- fix per dof synchronization
- split CMakeLists examples
- fix per dof synchronization with none
- separate trajectory and calculator class
- fix windows build
- code cleaning
- intermediate waypoints readme
- fix number of waypoints
- avoid pow completely
- update maintainer
- simplify readme
- use brake profile class
- fix finished trajectory for disabled dofs
- minor code cleaning
- Merge branch 'master' of github.com:pantor/ruckig
- add to_string for output parameters (#77)
- add ref to vel add_profile
- positional limits
- min limits for intermediate positions
- extend phase synchronization
- performance improvements
- add section to output in readme
- pass_to_input, did_section_change
- fix nullopt with c++11 patch
- fix nullopt in c++11 patch
- fix c++11
- per dof control interface and synchronization #53
- add section index to output
- Notes about Intermediate Waypoints
- interrupt calculation duration in microseconds
- add ruckig pro examples
- add ruckig toppra comparison
- improve readme and examples
- introduce Ruckig Pro
- remove generate docs ci
- link docs to ruckig.com
- add examples doc pages
- fix example names
- add more examples
- Instantaneous Motion Generation
- add calculation interruption
- add doxyfile again
- step1: numeric stability
- Contributors: Lars Berscheid, lpdon, pantor
0.4.0 (2021-08-23)
- update version to 0.4
- code cleaning
- add was_calculation_interrupted
- step 1: performance optimizations
- interrupt_calculation_duration
- Add CITATION.cff file
(#63)
- add CITATION.cff
- CITATOION wip
- fix cite
- Update README.md
- update to doctest 2.4.6
- code cleaning
- performance optimizations
- step 2: performance optimization
- step 2: performance optimization
- performance optimization: step 1
- performance optimization: positive set of roots
- performance optimization in step1
- code cleaning
- set find_package reflexxes to quiet
- remove BSD license text, why was it there anyway?
- clean plot trajectory
- add printing intermediate_positions
- code cleaning
- add degrees_of_freedom to python trajectory
- rename interface to control_interface
- set_limits for ACC1, code cleaning
- improve numeric stability
- in vel interface, change acc threshold
- code cleanup
- add DynamicDOFs constant
- numerical stability of velocity interface
- improve numerical stability
- fix variable name redeclaration
- fix jerk violation in step2, some optimizations
- clean up check methods of profile
- fix min_velocity with phas e synchronization
- fix phase synchronization in python
- improve numerical stability for high jerks
- fix newton step in acc0/acc1 for t=0
- clean up plot_trajectory
- validate for isnan
- fix python path in examples
- fix position extrema for dynamic number of dofs
- Added python example for non-realtime context
(#43)
- added python example for non-realtime context
- fixed ci workflow
- need to reset t_start
- rename
* change example Co-authored-by: Max Dhom <<md@adva.store>> Co-authored-by: Lars Berscheid <<lars.berscheid@kit.edu>>
- Dynamic Dofs (#47)
- vectorize
- use vector for dof==0
- add tests and checks
- include vector
- default dofs = 0, fix reflexxes
- redo default dofs template parameter
- add readme
- improve readme
- fix grammar
- add tests for invalid input
- add offline trajectory generation
- add paren to get time at position
- add get_first_time_at_position method
- Contributors: Lars Berscheid, Mathis, Max Dhom, pantor
0.3.3 (2021-06-25)
- Merge branch 'master' of github.com:pantor/ruckig
- version 0.3.3
- Set CMAKE_OUTPUT_DIRECTORY for windows build
(#41)
- check windows
- add library
- add debug log
- try to fix
- try to fix2
- try to fix 3
- try to fix 4
- fix 5
- rest test number
- fix setup.py
- remove log
- hard-code build directory of python library
- fix windows packge, version 0.3.2
- pre-compiled packages for windows on pypi
- Contributors: Lars Berscheid, pantor
0.3.1 (2021-06-24)
- set version 0.3.1
- add manifest.in
- double newton step in step2 vel udud
- Fix windows python package
(#38)
- fix windows
- update benchmark figure
- c++11 dont treat warnings as errors
- fix three step
- performance improvements
- vectorize dof
- Fix Patch for C++11
(#36)
- add ci for c++11
- remove maybe_unused
- patch in-place
- fix c++11
- replace make_unique
- find error in ci
- try to fix gcc-5
- dont build python
- dont patch cpp files
- deactivate cmake flags in patch script
- test python example
- add C++11 patch in readme
- add patch script for C++11
- Contributors: Lars Berscheid, pantor
0.3.0 (2021-06-16)
- update version number
- add python at_time comment for doxygen
- check for v_min, fix directional tests
- python return at_time method
- fix max target acceleration
- fix and test extremal positions
- synchronize function to trajectory class
- fix max target acceleration when min_velocity
- clean up docs
- fixed bug in check_position_extremum
(#33)
- fixed copy & paste error in Trajectory::is_phase_synchronizable
- fixed obvious copy & paste error in check_position_extremum
- fixed copy & paste error in Trajectory::is_phase_synchronizable (#32)
- fix negative, near zero pd cases
- Update README.md
- Update README.md
- Update README.md
- check limits with equal sign for numeric stability
- copy jerk_signs for phase synchronization
- remove alternative otgs
- add citation and link to paper
- remove alternative otgs from python
- fix numerical issues on time-optimal traj
- Merge branch 'master' of github.com:pantor/ruckig
- fix numeric error for long durations
- Scale to 5e9 random trajectories
- fix numerical issues
- add step through tests
- fix for braking
- double newton step
- fix macos and windows build
- recalculate after error
- fix some numerical issues
- use checkout@v2 in ci
- use ARCHIVE_OUTPUT_NAME for python wrapper
- msvc: warning as errors
- fix msvc compiler warnings
- Update README.md
- Update README.md
- Fix BUILD_PYTHON_MODULE option on Windows/MSVC (#18)
- fix ci args
- add phase synchronization
- set boundary method
- simplify python example
- Add pip install to Readme
- Contributors: Lars Berscheid, Silvio Traversaro, pantor, stefanbesler
0.2.6 (2021-03-29)
- remove env
- fix python cd
- use static library
- test python executable
- fix python package
- python cd: fix windows
- add setup.py, version 0.2.1
- rename python module to ruckig
- generate python classes for multiple dof
- Add a ROS package manifest (#10) Enables building Ruckig as a plain CMake package in a Catkin/Colcon workspace.
- fix end of brake trajectory integration
- Include GNU install dirs earlier (#11) Otherwise 'CMAKE_INSTALL_INCLUDEDIR' is empty/undefined when it's used to setup ruckig::ruckig's target_include_directories(..).
- readme: some minor typos (#9) I happened to notice them.
- privatize trajectory class members
- privatize some class members
- use cmath
- code cleaning
- show enum in docs
- split parameter files, calculate in trajectory
- code cleaning
- add python example
- Move options to API documentation
- Fix Readme Code
- fix undefined output for zero duration
- indicate default values in Readme
- add discrete durations
- Add Windows and macOS build to CI
(#4)
- windows and mac ci
- use cmake action for generator
- fix ci build directory
- run tests only on linux
- test example
- Add support to compile on Windows (#3)
- Merge pull request #2 from traversaro/patch-1 Use BUILD_SHARED_LIBS to select if compile C++ library as static or shared
- document examples/CMakeLists.txt
- add ci to PRs
- Use BUILD_SHARED_LIBS to select if compile as static or shared
- Merge pull request #1 from traversaro/add-install-support Add support for installation of the C++ library
- Add support for installation of the C++ library
- set correct cmake and doxygen version
- fix more edge cases
- fix some edge cases
- document velocity interface
- added velocity interface
- improve readme
- improve benchmark
- fix finding subdirectory
- check ci
- build python module in ci
- use own set class on stack
- fix synchronization enum, better python support
- add time synchronization parameter
- fix motion finished reset
- fix immediate reaction
- fix more edge cases
- refine min acceleration
- add min_acceleration
- fix some edge cases
- Merge branch 'master' of github.com:pantor/ruckig
- decrease required cmake to 3.10
- fix ci
- introduce trajectory class
- position extrema
- scale tests to 1e9
- several optimizations
- compile with warnings
- step2: code cleaning
- fix numeric edge cases
- move test suite to doctest
- fix cmake as submodule
- Merge branch 'master' of github.com:pantor/ruckig
- fix optional minimum time
- code documentation, more tests
- fix benchmark
- build benchmark in ci
- fix gcc
- remove eigen dep in cmake
- code cleaning
- code cleaning
- add comparison with multiple DoF
- rix ci: braking
- fix interval selection
- clean braking
- fix ci, more tests
- add benchmark, numeric stability
- fix block in step1
- clean root finding
- Increase stability
- improve tests, remove eigen
- code style
- increase test coverage
- add min_velocity
- fix ci
- Step1: Use Newton step
- fix ci
- fix time sync
- update tests
- more tests
- add example
- more tests
- increase number of tests
- simplify equations
- simplify equations
- simplify equations
- add tuple header
- further code cleaning
- remove eigen dependency, code cleaning
- clean brake code
- code cleaning
- code cleaning
- add doxygen
- improve acceleration target, readme
- refine max time deviation to 1e-8
- code cleaning
- improve time sync
- block synchronization
- stability for target acceleration in 1 dof
- update readme for ruckig
- add license
- improve tests
- fix eigen ci folder name
- fix eigen git repository
- fix 1dof vf comparison
- remove complex algorithmic
- code cleaning
- initial commit
- Contributors: G.A. vd. Hoorn, Lars Berscheid, Silvio Traversaro, pantor
Wiki Tutorials
Dependant Packages
Name | Deps |
---|---|
moveit_core |