@@ -72,14 +72,15 @@ controller_interface::InterfaceConfiguration ScaledJointTrajectoryController::st
7272 return conf;
7373}
7474
75- controller_interface::CallbackReturn ScaledJointTrajectoryController::on_activate (const rclcpp_lifecycle::State& state)
75+ controller_interface::CallbackReturn ScaledJointTrajectoryController::on_configure (const rclcpp_lifecycle::State& state)
7676{
77- TimeData time_data;
78- time_data.time = get_node ()->now ();
79- time_data.period = rclcpp::Duration::from_nanoseconds (0 );
80- time_data.uptime = get_node ()->now ();
81- time_data_.initRT (time_data);
77+ update_period_ = rclcpp::Duration (0.0 , static_cast <uint32_t >(1.0e9 / static_cast <double >(get_update_rate ())));
78+
79+ return JointTrajectoryController::on_configure (state);
80+ }
8281
82+ controller_interface::CallbackReturn ScaledJointTrajectoryController::on_activate (const rclcpp_lifecycle::State& state)
83+ {
8384 // Set scaling interfaces
8485 if (!scaled_params_.speed_scaling_interface_name .empty ()) {
8586 auto it = std::find_if (state_interfaces_.begin (), state_interfaces_.end (), [&](auto & interface) {
@@ -91,6 +92,7 @@ controller_interface::CallbackReturn ScaledJointTrajectoryController::on_activat
9192 RCLCPP_ERROR (get_node ()->get_logger (), " Did not find speed scaling interface in state interfaces." );
9293 }
9394 }
95+ last_commanded_time_ = rclcpp::Time ();
9496
9597 return JointTrajectoryController::on_activate (state);
9698}
@@ -101,7 +103,6 @@ controller_interface::return_type ScaledJointTrajectoryController::update(const
101103 if (scaling_state_interface_.has_value ()) {
102104 scaling_factor_ = scaling_state_interface_->get ().get_value ();
103105 }
104-
105106 if (get_state ().id () == lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE ) {
106107 return controller_interface::return_type::OK ;
107108 }
@@ -110,9 +111,14 @@ controller_interface::return_type ScaledJointTrajectoryController::update(const
110111 if (param_listener_->is_old (params_)) {
111112 params_ = param_listener_->get_params ();
112113 default_tolerances_ = get_segment_tolerances (logger, params_);
114+ // update the PID gains
115+ // variable use_closed_loop_pid_adapter_ is updated in on_configure only
116+ if (use_closed_loop_pid_adapter_) {
117+ update_pids ();
118+ }
113119 }
114120
115- auto compute_error_for_joint = [&](JointTrajectoryPoint& error, int index, const JointTrajectoryPoint& current,
121+ auto compute_error_for_joint = [&](JointTrajectoryPoint& error, size_t index, const JointTrajectoryPoint& current,
116122 const JointTrajectoryPoint& desired) {
117123 // error defined as the difference between current and desired
118124 if (joints_angle_wraparound_[index]) {
@@ -153,38 +159,36 @@ controller_interface::return_type ScaledJointTrajectoryController::update(const
153159 };
154160
155161 // current state update
156- state_current_.time_from_start .set__sec (0 );
162+ state_current_.time_from_start .sec = 0 ;
163+ state_current_.time_from_start .nanosec = 0 ;
157164 read_state_from_state_interfaces (state_current_);
158165
159166 // currently carrying out a trajectory
160167 if (has_active_trajectory ()) {
161- // Main Speed scaling difference...
162- // Adjust time with scaling factor
163- TimeData time_data;
164- time_data.time = time;
165- rcl_duration_value_t t_period = (time_data.time - time_data_.readFromRT ()->time ).nanoseconds ();
166- time_data.period = rclcpp::Duration::from_nanoseconds (scaling_factor_ * t_period);
167- time_data.uptime = time_data_.readFromRT ()->uptime + time_data.period ;
168- rclcpp::Time traj_time = time_data_.readFromRT ()->uptime + rclcpp::Duration::from_nanoseconds (t_period);
169- time_data_.reset ();
170- time_data_.initRT (time_data);
171-
172168 bool first_sample = false ;
173169 // if sampling the first time, set the point before you sample
174170 if (!traj_external_point_ptr_->is_sampled_already ()) {
175171 first_sample = true ;
176172 if (params_.open_loop_control ) {
177- traj_external_point_ptr_->set_point_before_trajectory_msg (traj_time , last_commanded_state_,
173+ traj_external_point_ptr_->set_point_before_trajectory_msg (last_commanded_time_ , last_commanded_state_,
178174 joints_angle_wraparound_);
179175 } else {
180- traj_external_point_ptr_->set_point_before_trajectory_msg (traj_time , state_current_, joints_angle_wraparound_);
176+ traj_external_point_ptr_->set_point_before_trajectory_msg (time , state_current_, joints_angle_wraparound_);
181177 }
178+ traj_time_ = time;
179+ } else {
180+ traj_time_ += period * scaling_factor_;
182181 }
182+ joint_trajectory_controller::TrajectoryPointConstIter start_segment_itr, end_segment_itr;
183+ // Sample expected state from the trajectory
184+ traj_external_point_ptr_->sample (traj_time_, interpolation_method_, state_desired_, start_segment_itr,
185+ end_segment_itr);
186+ state_desired_.time_from_start = traj_time_ - traj_external_point_ptr_->time_from_start ();
183187
184188 // find segment for current timestamp
185- joint_trajectory_controller::TrajectoryPointConstIter start_segment_itr, end_segment_itr;
186- const bool valid_point = traj_external_point_ptr_-> sample (traj_time, interpolation_method_, state_desired_,
187- start_segment_itr, end_segment_itr );
189+ const bool valid_point = traj_external_point_ptr_-> sample (traj_time_ + update_period_, interpolation_method_,
190+ command_next_, start_segment_itr, end_segment_itr);
191+ state_current_. time_from_start = time - traj_external_point_ptr_-> time_from_start ( );
188192
189193 if (valid_point) {
190194 const rclcpp::Time traj_start = traj_external_point_ptr_->time_from_start ();
@@ -195,7 +199,7 @@ controller_interface::return_type ScaledJointTrajectoryController::update(const
195199 // time_difference is
196200 // - negative until first point is reached
197201 // - counting from zero to time_from_start of next point
198- const double time_difference = time_data. uptime .seconds () - segment_time_from_start.seconds ();
202+ double time_difference = traj_time_ .seconds () - segment_time_from_start.seconds ();
199203 bool tolerance_violated_while_moving = false ;
200204 bool outside_goal_tolerance = false ;
201205 bool within_goal_time = true ;
@@ -246,32 +250,33 @@ controller_interface::return_type ScaledJointTrajectoryController::update(const
246250 if (use_closed_loop_pid_adapter_) {
247251 // Update PIDs
248252 for (auto i = 0ul ; i < dof_; ++i) {
249- tmp_command_[i] = (state_desired_ .velocities [i] * ff_velocity_scale_[i]) +
253+ tmp_command_[i] = (command_next_ .velocities [i] * ff_velocity_scale_[i]) +
250254 pids_[i]->computeCommand (state_error_.positions [i], state_error_.velocities [i],
251255 (uint64_t )period.nanoseconds ());
252256 }
253257 }
254258
255259 // set values for next hardware write()
256260 if (has_position_command_interface_) {
257- assign_interface_from_point (joint_command_interface_[0 ], state_desired_ .positions );
261+ assign_interface_from_point (joint_command_interface_[0 ], command_next_ .positions );
258262 }
259263 if (has_velocity_command_interface_) {
260264 if (use_closed_loop_pid_adapter_) {
261265 assign_interface_from_point (joint_command_interface_[1 ], tmp_command_);
262266 } else {
263- assign_interface_from_point (joint_command_interface_[1 ], state_desired_ .velocities );
267+ assign_interface_from_point (joint_command_interface_[1 ], command_next_ .velocities );
264268 }
265269 }
266270 if (has_acceleration_command_interface_) {
267- assign_interface_from_point (joint_command_interface_[2 ], state_desired_ .accelerations );
271+ assign_interface_from_point (joint_command_interface_[2 ], command_next_ .accelerations );
268272 }
269273 if (has_effort_command_interface_) {
270274 assign_interface_from_point (joint_command_interface_[3 ], tmp_command_);
271275 }
272276
273277 // store the previous command. Used in open-loop control mode
274- last_commanded_state_ = state_desired_;
278+ last_commanded_state_ = command_next_;
279+ last_commanded_time_ = time;
275280 }
276281
277282 if (active_goal) {
@@ -329,7 +334,7 @@ controller_interface::return_type ScaledJointTrajectoryController::update(const
329334 rt_active_goal_.writeFromNonRT (RealtimeGoalHandlePtr ());
330335 rt_has_pending_goal_ = false ;
331336
332- RCLCPP_WARN (logger, error_string.c_str ());
337+ RCLCPP_WARN (logger, " %s " , error_string.c_str ());
333338
334339 traj_msg_external_point_ptr_.reset ();
335340 traj_msg_external_point_ptr_.initRT (set_hold_position ());
@@ -357,6 +362,30 @@ controller_interface::return_type ScaledJointTrajectoryController::update(const
357362 return controller_interface::return_type::OK ;
358363}
359364
365+ void ScaledJointTrajectoryController::update_pids ()
366+ {
367+ for (size_t i = 0 ; i < dof_; ++i) {
368+ const auto & gains = params_.gains .joints_map .at (params_.joints [i]);
369+ if (pids_[i]) {
370+ // update PIDs with gains from ROS parameters
371+ pids_[i]->setGains (gains.p , gains.i , gains.d , gains.i_clamp , -gains.i_clamp );
372+ } else {
373+ // Init PIDs with gains from ROS parameters
374+ pids_[i] = std::make_shared<control_toolbox::Pid>(gains.p , gains.i , gains.d , gains.i_clamp , -gains.i_clamp );
375+ }
376+ // Check deprecated style for "ff_velocity_scale" parameter definition.
377+ if (gains.ff_velocity_scale == 0.0 ) {
378+ RCLCPP_WARN (get_node ()->get_logger (), " 'ff_velocity_scale' parameters is not defined under 'gains.<joint_name>.' "
379+ " structure. "
380+ " Maybe you are using deprecated format 'ff_velocity_scale/<joint_name>'!" );
381+
382+ ff_velocity_scale_[i] = auto_declare<double >(" ff_velocity_scale/" + params_.joints [i], 0.0 );
383+ } else {
384+ ff_velocity_scale_[i] = gains.ff_velocity_scale ;
385+ }
386+ }
387+ }
388+
360389} // namespace ur_controllers
361390
362391#include " pluginlib/class_list_macros.hpp"
0 commit comments