### Install Ruckig System-Wide or as Debian Package Source: https://docs.ruckig.com/installation This section explains how to install Ruckig after building it. Users can choose between a system-wide installation using 'make install' or package it as a Debian file using CPack. The latter involves running 'cpack' and then installing the generated .deb file. ```bash sudo make install ``` ```bash cpack sudo dpkg -i ruckig*.deb ``` -------------------------------- ### Online Trajectory Generation with Ruckig Source: https://docs.ruckig.com/example_14 Demonstrates online trajectory generation using the Ruckig library's Trackig class. It generates a trajectory based on a target state signal and updates the output for a specified number of time steps. This example requires Ruckig Pro. ```C++ #include #include #include "plotter.hpp" using namespace ruckig; // Create the target state signal TargetState<1> model_ramp(double t, double ramp_vel=0.5, double ramp_pos=1.0) { TargetState<1> target; const bool on_ramp = t < ramp_pos / std::abs(ramp_vel); target.position[0] = on_ramp ? t * ramp_vel : ramp_pos; target.velocity[0] = on_ramp ? ramp_vel : 0.0; target.acceleration[0] = 0.0; return target; } TargetState<1> model_constant_acceleration(double t, double ramp_acc=0.05) { TargetState<1> target; target.position[0] = t * t * ramp_acc; target.velocity[0] = t * ramp_acc; target.acceleration[0] = ramp_acc; return target; } TargetState<1> model_sinus(double t, double ramp_vel=0.4) { TargetState<1> target; target.position[0] = std::sin(ramp_vel * t); target.velocity[0] = ramp_vel * std::cos(ramp_vel * t); target.acceleration[0] = -ramp_vel * ramp_vel * std::sin(ramp_vel * t); return target; } int main() { // Create instances: the Trackig trajectory generator as well as input and output parameters Trackig<1> trackig(0.01); // control cycle InputParameter<1> input; OutputParameter<1> output; // Set input parameters 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}; // Optional minimum and maximum position input.min_position = {-2.5}; input.max_position = {2.5}; trackig.mode = TrackigMode::Optimized; // Optimized or Fast trackig.reactiveness = 1.0; // default value, should be in [0, 1] // Generate the trajectory following the target state std::cout << "target | follow" << std::endl; for (size_t t = 0; t < 500; t += 1) { const TargetState<1> target_state = model_ramp(trackig.delta_time * t); const Result res = trackig.update(target_state, input, output); std::cout << pretty_print(target_state.position) << " | " << pretty_print(output.new_position) << std::endl; output.pass_to_input(input); } } ruckig::Ruckig Main interface for the Ruckig algorithm. **Definition** ruckig.hpp:27 ruckig::Ruckig::update Result update(const InputParameter< DOFs, CustomVector > &input, OutputParameter< DOFs, CustomVector > &output) Get the next output state (with step delta_time) along the calculated trajectory for the given input. **Definition** ruckig.hpp:273 ruckig::Ruckig::delta_time double delta_time Time step between updates (control cycle time) **Definition** ruckig.hpp:68 ruckig **Definition** block.hpp:16 ruckig::Result Result Result type of methods calculating trajectories (e.g. Ruckig's and Trackig's update and calculate) **Definition** result.hpp:7 trackig.hpp ``` -------------------------------- ### Online Trajectory Generation with Ruckig (Python) Source: https://docs.ruckig.com/example_07 Generates a robot trajectory online using the Ruckig Python library. It initializes the generator with degrees of freedom and control cycle time, sets input parameters, and iteratively updates the trajectory. The output includes time and new position for each step, and prints the calculation and trajectory durations. This example also includes commented-out code for plotting the generated trajectory. ```python from ruckig import InputParameter, OutputParameter, Result, Ruckig if __name__ == '__main__': otg = Ruckig(3, 0.01) inp = InputParameter(3) out = OutputParameter(3) # Set input parameters inp.current_position = [0.0, 0.0, 0.5] inp.current_velocity = [0.0, -2.2, -0.5] inp.current_acceleration = [0.0, 2.5, -0.5] inp.target_position = [-5.0, -2.0, -3.5] inp.target_velocity = [0.0, -0.5, -2.0] inp.target_acceleration = [0.0, 0.0, 0.5] inp.max_velocity = [3.0, 1.0, 3.0] inp.max_acceleration = [3.0, 2.0, 1.0] inp.max_jerk = [4.0, 3.0, 2.0] # Set minimum duration (equals the trajectory duration when target velocity and acceleration are zero) inp.minimum_duration = 5.0 print('\t'.join(['t'] + [str(i) for i in range(otg.degrees_of_freedom)])) # Generate the trajectory within the control loop first_output, out_list = None, [] res = Result.Working while res == Result.Working: res = otg.update(inp, out) print('\t'.join([f'{out.time:0.3f}'] + [f'{p:0.3f}' for p in out.new_position])) out_list.append(copy(out)) out.pass_to_input(inp) if not first_output: first_output = copy(out) print(f'Calculation duration: {first_output.calculation_duration:0.1f} [µs]') print(f'Trajectory duration: {first_output.trajectory.duration:0.4f} [s]') # Plot the trajectory # from pathlib import Path # from plotter import Plotter # project_path = Path(__file__).parent.parent.absolute() # Plotter.plot_trajectory(project_path / 'examples' / '07_trajectory.pdf', otg, inp, out_list, plot_jerk=False) ``` -------------------------------- ### Install Ruckig Python Module Source: https://docs.ruckig.com/installation Provides instructions for installing the Ruckig Python module, primarily for development and debugging. The community version can be installed using pip. It also mentions building the Python module with CMake using a specific flag. ```bash pip install ruckig ``` ```bash pip install . ``` -------------------------------- ### Online Trajectory Generation with Stop Command (C++/Python) Source: https://docs.ruckig.com/example_06 This example demonstrates online trajectory generation using the Ruckig library. It initializes the trajectory generator with input parameters such as current and target positions, velocities, and accelerations. The trajectory is generated within a control loop, and a stop command can be issued dynamically. The output includes the time, new position, and the total duration of the trajectory. Dependencies include the Ruckig library and potentially a plotting utility. ```cpp #include #include "plotter.hpp" using namespace ruckig; int main() { // Create instances: the Ruckig trajectory generator as well as input and output parameters Ruckig<3> ruckig(0.01); InputParameter<3> input; OutputParameter<3> output; // Set input parameters input.current_position = {0.0, 0.0, 0.5}; input.current_velocity = {0.0, -2.2, -0.5}; input.current_acceleration = {0.0, 2.5, -0.5}; input.target_position = {5.0, -2.0, -3.5}; input.target_velocity = {0.0, -0.5, -2.0}; input.target_acceleration = {0.0, 0.0, 0.5}; input.max_velocity = {3.0, 1.0, 3.0}; input.max_acceleration = {3.0, 2.0, 1.0}; input.max_jerk = {4.0, 3.0, 2.0}; // Generate the trajectory within the control loop std::cout << "t | position" << std::endl; bool on_stop_trajectory = false; while (ruckig.update(input, output) == Result::Working) { std::cout << output.time << " | " << pretty_print(output.new_position) << std::endl; // Activate stop trajectory after 1s if (output.time >= 1.0 && !on_stop_trajectory) { std::cout << "Stop immediately." << std::endl; on_stop_trajectory = true; // Synchronization is disabled so that each DoF stops as fast as possible independently input.control_interface = ControlInterface::Velocity; input.synchronization = Synchronization::None; input.target_velocity = {0.0, 0.0, 0.0}; input.target_acceleration = {0.0, 0.0, 0.0}; input.max_jerk = {12.0, 10.0, 8.0}; } output.pass_to_input(input); } std::cout << "Stop trajectory duration: " << output.trajectory.get_duration() << " [s]." << std::endl; } ``` ```python from copy import copy from ruckig import InputParameter, OutputParameter, Result, Ruckig, ControlInterface, Synchronization if __name__ == '__main__': # Create instances: the Ruckig OTG as well as input and output parameters otg = Ruckig(3, 0.01) # DoFs, control cycle inp = InputParameter(3) out = OutputParameter(3) inp.current_position = [0.0, 0.0, 0.5] inp.current_velocity = [0.0, -2.2, -0.5] inp.current_acceleration = [0.0, 2.5, -0.5] inp.target_position = [5.0, -2.0, -3.5] inp.target_velocity = [0.0, -0.5, -2.0] inp.target_acceleration = [0.0, 0.0, 0.5] inp.max_velocity = [3.0, 1.0, 3.0] inp.max_acceleration = [3.0, 2.0, 1.0] inp.max_jerk = [4.0, 3.0, 2.0] print('\t'.join(['t'] + [str(i) for i in range(otg.degrees_of_freedom)])) # Generate the trajectory within the control loop first_output, out_list, time_offsets = None, [], [] on_stop_trajectory = False res = Result.Working while res == Result.Working: res = otg.update(inp, out) print('\t'.join([f'{out.time:0.3f}'] + [f'{p:0.3f}' for p in out.new_position])) out_list.append(copy(out)) time_offsets.append(1.0 if on_stop_trajectory else 0.0) # Activate stop trajectory after 1s if out.time >= 1.0 and not on_stop_trajectory: print('Stop immediately!') on_stop_trajectory = True # Synchronization is disabled so that each DoF stops as fast as possible independently inp.control_interface = ControlInterface.Velocity inp.synchronization = Synchronization.No inp.target_velocity = [0.0, 0.0, 0.0] inp.target_acceleration = [0.0, 0.0, 0.0] inp.max_jerk = [12.0, 10.0, 8.0] out.pass_to_input(inp) if not first_output: first_output = copy(out) print(f'Calculation duration: {first_output.calculation_duration:0.1f} [µs]') print(f'Trajectory duration: {first_output.trajectory.duration:0.4f} [s]') # Plot the trajectory # from pathlib import Path # from plotter import Plotter # project_path = Path(__file__).parent.parent.absolute() # Plotter.plot_trajectory(project_path / 'examples' / '06_trajectory.pdf', otg, inp, out_list, plot_jerk=False, time_offsets=time_offsets) ``` -------------------------------- ### Initialize Ruckig Instance with DoFs and Control Cycle Source: https://docs.ruckig.com/tutorial Initializes a Ruckig motion generation instance. It requires the number of Degrees of Freedom (DoFs) as a template parameter and the control cycle duration in seconds as a constructor argument. This is the fundamental step to start generating trajectories. ```cpp Ruckig<6> ruckig {0.001}; // Number DoFs; control cycle in [s] ``` -------------------------------- ### C++: Online Trajectory Generation with Intermediate Waypoints Source: https://docs.ruckig.com/example_03 This C++ example demonstrates the usage of intermediate waypoints for online trajectory generation using the Ruckig library. It requires Ruckig Pro or an enabled cloud API. The code initializes the Ruckig generator with specified degrees of freedom and control cycle, sets various input parameters including current and target states, and intermediate positions. It then iteratively updates the trajectory, printing the time and new position at each step, and finally reports the total trajectory duration and calculation time. ```C++ #include #include "plotter.hpp" using namespace ruckig; int main() { const double control_cycle = 0.01; const size_t DOFs = 3; const size_t max_number_of_waypoints = 10; // for memory allocation // Create instances: the Ruckig trajectory generator as well as input and output parameters Ruckig ruckig(control_cycle, max_number_of_waypoints); InputParameter input; OutputParameter output(max_number_of_waypoints); // Set input parameters input.current_position = {0.2, 0.0, -0.3}; input.current_velocity = {0.0, 0.2, 0.0}; input.current_acceleration = {0.0, 0.6, 0.0}; input.intermediate_positions = { {1.4, -1.6, 1.0}, {-0.6, -0.5, 0.4}, {-0.4, -0.35, 0.0}, {0.8, 1.8, -0.1} }; input.target_position = {0.5, 1.0, 0.0}; input.target_velocity = {0.2, 0.0, 0.3}; input.target_acceleration = {0.0, 0.1, -0.1}; input.max_velocity = {1.0, 2.0, 1.0}; input.max_acceleration = {3.0, 2.0, 2.0}; input.max_jerk = {6.0, 10.0, 20.0}; std::cout << "t | position" << std::endl; double calculation_duration = 0.0; while (ruckig.update(input, output) == Result::Working) { std::cout << output.time << " | " << pretty_print(output.new_position) << std::endl; output.pass_to_input(input); if (output.new_calculation) { calculation_duration = output.calculation_duration; } } std::cout << "Reached target position in " << output.trajectory.get_duration() << " [s]." << std::endl; std::cout << "Calculation in " << calculation_duration << " [µs]." << std::endl; } ``` -------------------------------- ### C++/Python: Online Trajectory Generation with Intermediate Waypoints Source: https://docs.ruckig.com/example_08 This example demonstrates the usage of intermediate waypoints for online trajectory generation using the Ruckig library. It requires Ruckig Pro or the enabled cloud API. The code sets up input parameters including current and target positions, velocities, accelerations, and maximum limits, along with intermediate positions and per-section minimum durations. It then iteratively updates the trajectory within a control loop, printing the time and new position at each step. The output includes the total trajectory duration and the calculation time. ```cpp #include #include "plotter.hpp" using namespace ruckig; int main() { const double control_cycle = 0.01; const size_t DOFs = 3; const size_t max_number_of_waypoints = 10; // for memory allocation // Create instances: the Ruckig trajectory generator as well as input and output parameters Ruckig ruckig(control_cycle, max_number_of_waypoints); InputParameter input; OutputParameter output(max_number_of_waypoints); // Set input parameters input.current_position = {0.8, 0.0, 0.5}; input.current_velocity = {0.0, 0.0, 0.0}; input.current_acceleration = {0.0, 0.0, 0.0}; input.intermediate_positions = { {1.4, -1.6, 1.0}, {-0.6, -0.5, 0.4}, {-0.4, -0.35, 0.0}, {-0.2, 0.35, -0.1}, {0.2, 0.5, -0.1}, {0.8, 1.8, -0.1} }; input.target_position = {0.5, 1.2, 0.0}; input.target_velocity = {0.0, 0.0, 0.0}; input.target_acceleration = {0.0, 0.0, 0.0}; input.max_velocity = {3.0, 2.0, 2.0}; input.max_acceleration = {6.0, 4.0, 4.0}; input.max_jerk = {16.0, 10.0, 20.0}; // Define a minimum duration per section of the trajectory (number waypoints + 1) input.per_section_minimum_duration = {0, 2.0, 0.0, 1.0, 0.0, 2.0, 0}; std::cout << "t | position" << std::endl; double calculation_duration = 0.0; while (ruckig.update(input, output) == Result::Working) { std::cout << output.time << " | " << pretty_print(output.new_position) << std::endl; output.pass_to_input(input); if (output.new_calculation) { calculation_duration = output.calculation_duration; } } std::cout << "Reached target position in " << output.trajectory.get_duration() << " [s]." << std::endl; std::cout << "Calculation in " << calculation_duration << " [µs]." << std::endl; } ``` ```python from copy import copy from ruckig import InputParameter, OutputParameter, Result, Ruckig if __name__ == '__main__': # Create instances: the Ruckig OTG as well as input and output parameters otg = Ruckig(3, 0.01, 10) # DoFs, control cycle rate, maximum number of intermediate waypoints for memory allocation inp = InputParameter(3) # DoFs out = OutputParameter(3, 10) # DoFs, maximum number of intermediate waypoints for memory allocation inp.current_position = [0.8, 0, 0.5] inp.current_velocity = [0, 0, 0] inp.current_acceleration = [0, 0, 0] inp.intermediate_positions = [ [1.4, -1.6, 1.0], [-0.6, -0.5, 0.4], [-0.4, -0.35, 0.0], [-0.2, 0.35, -0.1], [0.2, 0.5, -0.1], [0.8, 1.8, -0.1], ] inp.target_position = [0.5, 1.2, 0] inp.target_velocity = [0, 0, 0] inp.target_acceleration = [0, 0, 0] inp.max_velocity = [3, 2, 2] inp.max_acceleration = [6, 4, 4] inp.max_jerk = [16, 10, 20] # Define a minimum duration per section of the trajectory (number waypoints + 1) inp.per_section_minimum_duration = [0, 2.0, 0.0, 1.0, 0.0, 2.0, 0] print('\t'.join(['t'] + [str(i) for i in range(otg.degrees_of_freedom)])) # Generate the trajectory within the control loop first_output, out_list = None, [] res = Result.Working while res == Result.Working: res = otg.update(inp, out) print('\t'.join([f'{out.time:0.3f}'] + [f'{p:0.3f}' for p in out.new_position])) out_list.append(copy(out)) out.pass_to_input(inp) if not first_output: first_output = copy(out) print(f'Calculation duration: {first_output.calculation_duration:0.1f} [µs]') print(f'Trajectory duration: {first_output.trajectory.duration:0.4f} [s]') # Plot the trajectory # from pathlib import Path # from plotter import Plotter # project_path = Path(__file__).parent.parent.absolute() # Plotter.plot_trajectory(project_path / 'examples' / '08_trajectory.pdf', otg, inp, out_list, plot_jerk=False) ``` -------------------------------- ### Include Ruckig Headers for Motion Calculation Source: https://docs.ruckig.com/calculator_8hpp Includes necessary C++ headers for the Ruckig library to perform motion generation calculations. This setup is crucial for utilizing the library's features for robots and machines. ```cpp #include #include #include #include #include #include ``` -------------------------------- ### Python: Online Trajectory Generation with Intermediate Waypoints Source: https://docs.ruckig.com/example_03 This Python example demonstrates online trajectory generation with intermediate waypoints using the Ruckig library. It requires Ruckig Pro or an enabled cloud API. The script initializes the Ruckig OTG, sets input parameters including current and target states, and intermediate positions. It then enters a loop to update the trajectory iteratively, printing the time and new position. Finally, it reports the calculation duration and total trajectory duration. ```Python from copy import copy from ruckig import InputParameter, OutputParameter, Result, Ruckig if __name__ == '__main__': # Create instances: the Ruckig OTG as well as input and output parameters otg = Ruckig(3, 0.01, 10) # DoFs, control cycle rate, maximum number of intermediate waypoints for memory allocation inp = InputParameter(3) # DoFs out = OutputParameter(3, 10) # DoFs, maximum number of intermediate waypoints for memory allocation inp.current_position = [0.2, 0, -0.3] inp.current_velocity = [0, 0.2, 0] inp.current_acceleration = [0, 0.6, 0] inp.intermediate_positions = [ [1.4, -1.6, 1.0], [-0.6, -0.5, 0.4], [-0.4, -0.35, 0.0], [0.8, 1.8, -0.1], ] inp.target_position = [0.5, 1, 0] inp.target_velocity = [0.2, 0, 0.3] inp.target_acceleration = [0, 0.1, -0.1] inp.max_velocity = [1, 2, 1] inp.max_acceleration = [3, 2, 2] inp.max_jerk = [6, 10, 20] print('\t'.join(['t'] + [str(i) for i in range(otg.degrees_of_freedom)])) # Generate the trajectory within the control loop first_output, out_list = None, [] res = Result.Working while res == Result.Working: res = otg.update(inp, out) print('\t'.join([f'{out.time:0.3f}'] + [f'{p:0.3f}' for p in out.new_position])) out_list.append(copy(out)) out.pass_to_input(inp) if not first_output: first_output = copy(out) print(f'Calculation duration: {first_output.calculation_duration:0.1f} [µs]') print(f'Trajectory duration: {first_output.trajectory.duration:0.4f} [s]') # Plot the trajectory # from pathlib import Path # from plotter import Plotter # project_path = Path(__file__).parent.parent.absolute() # Plotter.plot_trajectory(project_path / 'examples' / '03_trajectory.pdf', otg, inp, out_list, plot_jerk=False) ``` -------------------------------- ### C++: Online Trajectory Generation with Intermediate Waypoints Source: https://docs.ruckig.com/example_10 This C++ example demonstrates the usage of intermediate waypoints in online trajectory generation using the Ruckig library. It requires Ruckig Pro or an enabled cloud API. The code generates a trajectory that passes through specified intermediate positions before reaching the target. ```C++ #include #include "plotter.hpp" using namespace ruckig; int main() { double control_cycle = 0.01; size_t DOFs = 3; size_t max_number_of_waypoints = 10; // for memory allocation // Create instances: the Ruckig trajectory generator as well as input and output parameters Ruckig ruckig(DOFs, control_cycle, max_number_of_waypoints); InputParameter input(DOFs); OutputParameter output(DOFs, max_number_of_waypoints); // Set input parameters input.current_position = {0.2, 0.0, -0.3}; input.current_velocity = {0.0, 0.2, 0.0}; input.current_acceleration = {0.0, 0.6, 0.0}; input.intermediate_positions = { {1.4, -1.6, 1.0}, {-0.6, -0.5, 0.4}, {-0.4, -0.35, 0.0}, {0.8, 1.8, -0.1} }; input.target_position = {0.5, 1.0, 0.0}; input.target_velocity = {0.2, 0.0, 0.3}; input.target_acceleration = {0.0, 0.1, -0.1}; input.max_velocity = {1.0, 2.0, 1.0}; input.max_acceleration = {3.0, 2.0, 2.0}; input.max_jerk = {6.0, 10.0, 20.0}; std::cout << "t | position" << std::endl; double calculation_duration = 0.0; while (ruckig.update(input, output) == Result::Working) { std::cout << output.time << " | " << pretty_print(output.new_position) << std::endl; output.pass_to_input(input); if (output.new_calculation) { calculation_duration = output.calculation_duration; } } std::cout << "Reached target position in " << output.trajectory.get_duration() << " [s]." << std::endl; std::cout << "Calculation in " << calculation_duration << " [µs]." << std::endl; } ``` -------------------------------- ### Ruckig InputParameter Constructors Source: https://docs.ruckig.com/classruckig_1_1InputParameter Provides constructors for the Ruckig InputParameter class. These constructors allow initialization with a specified number of degrees of freedom and optionally a maximum number of waypoints, enabling flexible setup for different robotic systems. ```cpp template class CustomVector = StandardVector> class ruckig::InputParameter< DOFs, CustomVector > // Constructor 1/6: Default constructor for when DOFs >= 1 template class CustomVector = StandardVector> template=1), int >::type = 0> rückig::InputParameter< DOFs, CustomVector >::InputParameter() inline // Constructor 2/6: Constructor for specifying DOFs when D == 0 template class CustomVector = StandardVector> template::type = 0> rückig::InputParameter< DOFs, CustomVector >::InputParameter(size_t _dofs_) inline // Constructor 3/6: Constructor for specifying max waypoints when DOFs >= 1 template class CustomVector = StandardVector> template=1), int >::type = 0> rückig::InputParameter< DOFs, CustomVector >::InputParameter(size_t _max_number_of_waypoints_) inline // Constructor 4/6: Constructor for specifying DOFs and max waypoints when D == 0 template class CustomVector = StandardVector> template::type = 0> rückig::InputParameter< DOFs, CustomVector >::InputParameter(size_t _dofs_, size_t _max_number_of_waypoints_) inline ``` -------------------------------- ### Ruckig Online Trajectory Generation with Intermediate Waypoints (C++/Python) Source: https://docs.ruckig.com/example_04 Demonstrates the usage of intermediate waypoints for Ruckig trajectory generation. This example requires Ruckig Pro or an enabled cloud API. It sets up input parameters including current and target states, intermediate positions, and kinematic limits, then iteratively updates the trajectory within a control loop. ```cpp #include #include "plotter.hpp" using namespace ruckig; int main() { const double control_cycle = 0.01; const size_t DOFs = 3; const size_t max_number_of_waypoints = 10; // for memory allocation // Create instances: the Ruckig trajectory generator as well as input and output parameters Ruckig ruckig(control_cycle, max_number_of_waypoints); InputParameter input; OutputParameter output(max_number_of_waypoints); // Set input parameters input.current_position = {0.2, 0.0, -0.3}; input.current_velocity = {0.0, 0.2, 0.0}; input.current_acceleration = {0.0, 0.6, 0.0}; input.intermediate_positions = { {1.4, -1.6, 1.0}, {-0.6, -0.5, 0.4}, {-0.4, -0.35, 0.0}, {0.8, 1.8, -0.1} }; input.target_position = {0.5, 1.0, 0.0}; input.target_velocity = {0.2, 0.0, 0.3}; input.target_acceleration = {0.0, 0.1, -0.1}; input.max_velocity = {1.0, 2.0, 1.0}; input.max_acceleration = {3.0, 2.0, 2.0}; input.max_jerk = {6.0, 10.0, 20.0}; input.interrupt_calculation_duration = 500; // [µs] std::cout << "t | position" << std::endl; double calculation_duration = 0.0; while (ruckig.update(input, output) == Result::Working) { if (output.new_calculation) { std::cout << "Updated the trajectory:" << std::endl; std::cout << " Reached target position in " << output.trajectory.get_duration() << " [s]." << std::endl; std::cout << " Calculation in " << output.calculation_duration << " [µs]." << std::endl; } std::cout << output.time << " | " << pretty_print(output.new_position) << std::endl; output.pass_to_input(input); } } ``` ```python from copy import copy from ruckig import InputParameter, OutputParameter, Result, Ruckig if __name__ == '__main__': # Create instances: the Ruckig OTG as well as input and output parameters otg = Ruckig(3, 0.01, 10) # DoFs, control cycle rate, maximum number of intermediate waypoints for memory allocation inp = InputParameter(3) # DoFs out = OutputParameter(3, 10) # DoFs, maximum number of intermediate waypoints for memory allocation inp.current_position = [0.2, 0, -0.3] inp.current_velocity = [0, 0.2, 0] inp.current_acceleration = [0, 0.6, 0] inp.intermediate_positions = [ [1.4, -1.6, 1.0], [-0.6, -0.5, 0.4], [-0.4, -0.35, 0.0], [0.8, 1.8, -0.1], ] inp.target_position = [0.5, 1, 0] inp.target_velocity = [0.2, 0, 0.3] inp.target_acceleration = [0, 0.1, -0.1] inp.max_velocity = [1, 2, 1] inp.max_acceleration = [3, 2, 2] inp.max_jerk = [6, 10, 20] inp.interrupt_calculation_duration = 500 # [µs] print('\t'.join(['t'] + [str(i) for i in range(otg.degrees_of_freedom)])) # Generate the trajectory within the control loop out_list = [] res = Result.Working while res == Result.Working: res = otg.update(inp, out) if out.new_calculation: print('Updated the trajectory:') print(f' Calculation duration: {out.calculation_duration:0.1f} [µs]') print(f' Trajectory duration: {out.trajectory.duration:0.4f} [s]') print('\t'.join([f'{out.time:0.3f}'] + [f'{p:0.3f}' for p in out.new_position])) out_list.append(copy(out)) out.pass_to_input(inp) # Plot the trajectory # from pathlib import Path # from plotter import Plotter # project_path = Path(__file__).parent.parent.absolute() # Plotter.plot_trajectory(project_path / 'examples' / '04_trajectory.pdf', otg, inp, out_list, plot_jerk=False) ``` -------------------------------- ### Dynamic DOFs Trajectory Generation with Custom Vector (C++) Source: https://docs.ruckig.com/example_13 Demonstrates online trajectory generation using Ruckig with a dynamic number of degrees of freedom and a custom vector type. It initializes the Ruckig generator, sets input parameters such as current and target positions/velocities/accelerations, and maximum limits. The trajectory is generated iteratively within a control loop, printing the time and new position at each step. Finally, it prints the total trajectory duration. This example requires the Ruckig library and a plotter utility. ```cpp #include #include #include "plotter.hpp" template class MinimalDynamicDofsVector { std::deque data; public: MinimalDynamicDofsVector() { } MinimalDynamicDofsVector(std::initializer_list a) { data.resize(a.size()); std::copy_n(a.begin(), a.size(), std::begin(data)); } T operator[](size_t i) const { return data[i]; } T& operator[](size_t i) { return data[i]; } size_t size() const { return data.size(); } void resize(size_t size) { data.resize(size); } bool operator==(const MinimalDynamicDofsVector& rhs) const { for (size_t dof = 0; dof < data.size(); ++dof) { if (data[dof] != rhs[dof]) { return false; } } return true; } }; using namespace ruckig; int main() { // Create instances: the Ruckig trajectory generator as well as input and output parameters Ruckig ruckig(3, 0.01); // control cycle InputParameter input(3); OutputParameter output(3); // Set input parameters input.current_position = {0.0, 0.0, 0.5}; input.current_velocity = {0.0, -2.2, -0.5}; input.current_acceleration = {0.0, 2.5, -0.5}; input.target_position = {5.0, -2.0, -3.5}; input.target_velocity = {0.0, -0.5, -2.0}; input.target_acceleration = {0.0, 0.0, 0.5}; input.max_velocity = {3.0, 1.0, 3.0}; input.max_acceleration = {3.0, 2.0, 1.0}; input.max_jerk = {4.0, 3.0, 2.0}; // Generate the trajectory within the control loop std::cout << "t | position" << std::endl; while (ruckig.update(input, output) == Result::Working) { std::cout << output.time << " | " << pretty_print(output.new_position) << std::endl; output.pass_to_input(input); } std::cout << "Trajectory duration: " << output.trajectory.get_duration() << " [s]." << std::endl; } ``` -------------------------------- ### Python Trajectory Generation Source: https://docs.ruckig.com/example_11 Demonstrates trajectory generation using the Ruckig library in Python. This example highlights that custom vector types used in C++ do not impact the Python implementation, suggesting a simplified interface for Python users. ```python # --- # # Nothing to see here, as the custom vector types don't affect the Python version. # # --- ``` -------------------------------- ### Online Trajectory Generation with Ruckig (C++) Source: https://docs.ruckig.com/example_07 Generates a robot trajectory online using the Ruckig C++ library. It initializes the generator with control cycle time, sets input parameters like current and target positions/velocities/accelerations, and iteratively updates the trajectory until completion. The output includes time and new position at each step, and the total trajectory duration. ```cpp #include #include "plotter.hpp" using namespace ruckig; int main() { // Create instances: the Ruckig trajectory generator as well as input and output parameters Ruckig<3> ruckig(0.01); // control cycle InputParameter<3> input; OutputParameter<3> output; // Set input parameters input.current_position = {0.0, 0.0, 0.5}; input.current_velocity = {0.0, -2.2, -0.5}; input.current_acceleration = {0.0, 2.5, -0.5}; input.target_position = {-5.0, -2.0, -3.5}; input.target_velocity = {0.0, -0.5, -2.0}; input.target_acceleration = {0.0, 0.0, 0.5}; input.max_velocity = {3.0, 1.0, 3.0}; input.max_acceleration = {3.0, 2.0, 1.0}; input.max_jerk = {4.0, 3.0, 2.0}; // Set minimum duration (equals the trajectory duration when target velocity and acceleration are zero) input.minimum_duration = 5.0; // Generate the trajectory within the control loop std::cout << "t | position" << std::endl; while (ruckig.update(input, output) == Result::Working) { std::cout << output.time << " | " << pretty_print(output.new_position) << std::endl; output.pass_to_input(input); } std::cout << "Trajectory duration: " << output.trajectory.get_duration() << " [s]." << std::endl; } ``` -------------------------------- ### Offline Trajectory Calculation in Python Source: https://docs.ruckig.com/example_02 Illustrates the use of the Ruckig library in Python for offline trajectory generation. Similar to the C++ example, it involves defining input parameters and then calculating the trajectory. The code retrieves the trajectory's duration and kinematic states at a given time, demonstrating a Pythonic approach. ```python from ruckig import InputParameter, Ruckig, Trajectory, Result if __name__ == '__main__': inp = InputParameter(3) inp.current_position = [0.0, 0.0, 0.5] inp.current_velocity = [0.0, -2.2, -0.5] inp.current_acceleration = [0.0, 2.5, -0.5] inp.target_position = [5.0, -2.0, -3.5] inp.target_velocity = [0.0, -0.5, -2.0] inp.target_acceleration = [0.0, 0.0, 0.5] inp.max_velocity = [3.0, 1.0, 3.0] inp.max_acceleration = [3.0, 2.0, 1.0] inp.max_jerk = [4.0, 3.0, 2.0] # Set different constraints for negative direction inp.min_velocity = [-1.0, -0.5, -3.0] inp.min_acceleration = [-2.0, -1.0, -2.0] # We don't need to pass the control rate (cycle time) when using only offline features otg = Ruckig(3) trajectory = Trajectory(3) # Calculate the trajectory in an offline manner result = otg.calculate(inp, trajectory) if result == Result.ErrorInvalidInput: raise Exception('Invalid input!') print(f'Trajectory duration: {trajectory.duration:0.4f} [s]') new_time = 1.0 # Then, we can calculate the kinematic state at a given time new_position, new_velocity, new_acceleration = trajectory.at_time(new_time) print(f'Position at time {new_time:0.4f} [s]: {new_position}') # Get some info about the position extrema of the trajectory print(f'Position extremas are {trajectory.position_extrema}') ```