1818
1919#include < memory>
2020#include < string>
21+ #include < vector>
2122
2223#include " joint_limits/joint_limits_rosparam.hpp"
2324#include " rcutils/logging_macros.h"
25+ #include " ruckig/brake.hpp"
2426#include " ruckig/input_parameter.hpp"
2527#include " ruckig/output_parameter.hpp"
2628#include " ruckig/ruckig.hpp"
@@ -34,34 +36,48 @@ RuckigJointLimiter<joint_limits::JointLimits>::RuckigJointLimiter()
3436}
3537
3638template <>
37- bool RuckigJointLimiter<joint_limits::JointLimits>::on_init()
39+ bool RuckigJointLimiter<joint_limits::JointLimits>::on_init(/* const rclcpp::Duration & dt */ )
3840{
41+ // TODO(destogl): This should be used from parameter
42+ const rclcpp::Duration dt = rclcpp::Duration::from_seconds (0.005 );
43+
3944 // Initialize Ruckig
40- ruckig_ = std::make_shared<ruckig::Ruckig<0 >>(number_of_joints_, 0.01 /* timestep */ );
45+ ruckig_ = std::make_shared<ruckig::Ruckig<0 >>(number_of_joints_, dt. seconds () );
4146 ruckig_input_ = std::make_shared<ruckig::InputParameter<0 >>(number_of_joints_);
4247 ruckig_output_ = std::make_shared<ruckig::OutputParameter<0 >>(number_of_joints_);
4348
4449 // Velocity mode works best for smoothing one waypoint at a time
4550 ruckig_input_->control_interface = ruckig::ControlInterface::Velocity;
51+ ruckig_input_->synchronization = ruckig::Synchronization::Time;
4652
4753 for (auto joint = 0ul ; joint < number_of_joints_; ++joint)
4854 {
4955 if (joint_limits_[joint].has_jerk_limits )
5056 {
5157 ruckig_input_->max_jerk .at (joint) = joint_limits_[joint].max_acceleration ;
5258 }
59+ else
60+ {
61+ ruckig_input_->max_jerk .at (joint) = DEFAULT_MAX_JERK;
62+ }
5363 if (joint_limits_[joint].has_acceleration_limits )
5464 {
5565 ruckig_input_->max_acceleration .at (joint) = joint_limits_[joint].max_acceleration ;
5666 }
67+ else
68+ {
69+ ruckig_input_->max_acceleration .at (joint) = DEFAULT_MAX_ACCELERATION;
70+ }
5771 if (joint_limits_[joint].has_velocity_limits )
5872 {
5973 ruckig_input_->max_velocity .at (joint) = joint_limits_[joint].max_velocity ;
6074 }
75+ else
76+ {
77+ ruckig_input_->max_velocity .at (joint) = DEFAULT_MAX_VELOCITY;
78+ }
6179 }
6280
63- RCUTILS_LOG_INFO_NAMED (" ruckig_joint_limiter" , " Successfully initialized." );
64-
6581 return true ;
6682}
6783
@@ -70,15 +86,24 @@ bool RuckigJointLimiter<joint_limits::JointLimits>::on_configure(
7086 const trajectory_msgs::msg::JointTrajectoryPoint & current_joint_states)
7187{
7288 // Initialize Ruckig with current_joint_states
73- std::copy_n (
74- current_joint_states.positions .begin (), number_of_joints_,
75- ruckig_input_->current_position .begin ());
76- std::copy_n (
77- current_joint_states.velocities .begin (), number_of_joints_,
78- ruckig_input_->current_velocity .begin ());
79- std::copy_n (
80- current_joint_states.accelerations .begin (), number_of_joints_,
81- ruckig_input_->current_acceleration .begin ());
89+ ruckig_input_->current_position = current_joint_states.positions ;
90+
91+ if (current_joint_states.velocities .size () == number_of_joints_)
92+ {
93+ ruckig_input_->current_velocity = current_joint_states.velocities ;
94+ }
95+ else
96+ {
97+ ruckig_input_->current_velocity = std::vector<double >(number_of_joints_, 0.0 );
98+ }
99+ if (current_joint_states.accelerations .size () == number_of_joints_)
100+ {
101+ ruckig_input_->current_acceleration = current_joint_states.accelerations ;
102+ }
103+ else
104+ {
105+ ruckig_input_->current_acceleration = std::vector<double >(number_of_joints_, 0.0 );
106+ }
82107
83108 // Initialize output data
84109 ruckig_output_->new_position = ruckig_input_->current_position ;
@@ -96,20 +121,54 @@ bool RuckigJointLimiter<joint_limits::JointLimits>::on_enforce(
96121{
97122 // We don't use current_joint_states. For stability, it is recommended to feed previous Ruckig
98123 // output back in as input for the next iteration. This assumes the robot tracks the command well.
124+ ruckig_input_->current_position = ruckig_output_->new_position ;
125+ ruckig_input_->current_velocity = ruckig_output_->new_velocity ;
126+ ruckig_input_->current_acceleration = ruckig_output_->new_acceleration ;
127+
128+ // Target state is the next waypoint
129+ ruckig_input_->target_position = desired_joint_states.positions ;
130+ // TODO(destogl): in current use-case we use only velocity
131+ if (desired_joint_states.velocities .size () == number_of_joints_)
132+ {
133+ ruckig_input_->target_velocity = desired_joint_states.velocities ;
134+ }
135+ else
136+ {
137+ ruckig_input_->target_velocity = std::vector<double >(number_of_joints_, 0.0 );
138+ }
139+ if (desired_joint_states.accelerations .size () == number_of_joints_)
140+ {
141+ ruckig_input_->target_acceleration = desired_joint_states.accelerations ;
142+ }
143+ else
144+ {
145+ ruckig_input_->target_acceleration = std::vector<double >(number_of_joints_, 0.0 );
146+ }
147+
148+ ruckig::Result result = ruckig_->update (*ruckig_input_, *ruckig_output_);
149+ RCUTILS_LOG_DEBUG_NAMED (" ruckig_joint_limiter" , " Rucking result %d" , result);
150+
151+ desired_joint_states.positions = ruckig_output_->new_position ;
152+ desired_joint_states.velocities = ruckig_output_->new_velocity ;
153+ desired_joint_states.accelerations = ruckig_output_->new_acceleration ;
99154
100155 // Feed output from the previous timestep back as input
101156 for (auto joint = 0ul ; joint < number_of_joints_; ++joint)
102157 {
103- ruckig_input_->current_position .at (joint) = ruckig_output_->new_position .at (joint);
104- ruckig_input_->current_velocity .at (joint) = ruckig_output_->new_velocity .at (joint);
105- ruckig_input_->current_acceleration .at (joint) = ruckig_output_->new_acceleration .at (joint);
106-
107- // Target state is the next waypoint
108- ruckig_input_->target_velocity .at (joint) = desired_joint_states.velocities .at (joint);
109- ruckig_input_->target_acceleration .at (joint) = desired_joint_states.accelerations .at (joint);
158+ RCUTILS_LOG_DEBUG_NAMED (
159+ " ruckig_joint_limiter" ,
160+ " Desired position: %e \n Desired velocity: %e\n Desired acceleration: %e." ,
161+ ruckig_input_->target_position .at (joint), ruckig_input_->target_velocity .at (joint),
162+ ruckig_input_->target_acceleration .at (joint));
110163 }
111164
112- ruckig::Result result = ruckig_->update (*ruckig_input_, *ruckig_output_);
165+ for (auto joint = 0ul ; joint < number_of_joints_; ++joint)
166+ {
167+ RCUTILS_LOG_DEBUG_NAMED (
168+ " ruckig_joint_limiter" , " New position: %e \n New velocity: %e\n New acceleration: %e." ,
169+ ruckig_output_->new_position .at (joint), ruckig_output_->new_velocity .at (joint),
170+ ruckig_output_->new_acceleration .at (joint));
171+ }
113172
114173 return result == ruckig::Result::Finished;
115174}
0 commit comments