@@ -189,39 +189,48 @@ controller_interface::return_type JointTrajectoryController::update(
189189 const bool before_last_point = end_segment_itr != (*traj_point_active_ptr_)->end ();
190190
191191 // set values for next hardware write()
192+ if (use_closed_loop_pid_adapter)
193+ {
194+ // Update PIDs
195+ for (auto i = 0ul ; i < joint_num; ++i)
196+ {
197+ tmp_command_[i] = (state_desired.velocities [i] * ff_velocity_scale_[i]) +
198+ pids_[i]->computeCommand (
199+ state_desired.positions [i] - state_current.positions [i],
200+ state_desired.velocities [i] - state_current.velocities [i],
201+ (uint64_t )period.nanoseconds ());
202+ }
203+ }
192204 if (has_position_command_interface_)
193205 {
194206 assign_interface_from_point (joint_command_interface_[0 ], state_desired.positions );
195207 }
196208 if (has_velocity_command_interface_)
197209 {
198- if (! use_closed_loop_pid_adapter)
210+ if (use_closed_loop_pid_adapter)
199211 {
200- assign_interface_from_point (joint_command_interface_[1 ], state_desired. velocities );
212+ assign_interface_from_point (joint_command_interface_[1 ], tmp_command_ );
201213 }
202214 else
203215 {
204- // Update PIDs
205- for (auto i = 0ul ; i < joint_num; ++i)
206- {
207- tmp_command_[i] = (state_desired.velocities [i] * ff_velocity_scale_[i]) +
208- pids_[i]->computeCommand (
209- state_desired.positions [i] - state_current.positions [i],
210- state_desired.velocities [i] - state_current.velocities [i],
211- (uint64_t )period.nanoseconds ());
212- }
213- assign_interface_from_point (joint_command_interface_[1 ], tmp_command_);
216+ assign_interface_from_point (joint_command_interface_[1 ], state_desired.velocities );
214217 }
215218 }
216219 if (has_acceleration_command_interface_)
217220 {
218221 assign_interface_from_point (joint_command_interface_[2 ], state_desired.accelerations );
219222 }
220- // TODO(anyone): Add here "if using_closed_loop_hw_interface_adapter" (see ROS1) - #171
221- // if (check_if_interface_type_exist(
222- // command_interface_types_, hardware_interface::HW_IF_EFFORT)) {
223- // assign_interface_from_point(joint_command_interface_[3], state_desired.effort);
224- // }
223+ if (has_effort_command_interface_)
224+ {
225+ if (use_closed_loop_pid_adapter)
226+ {
227+ assign_interface_from_point (joint_command_interface_[3 ], tmp_command_);
228+ }
229+ else
230+ {
231+ assign_interface_from_point (joint_command_interface_[3 ], state_desired.effort );
232+ }
233+ }
225234
226235 for (size_t index = 0 ; index < joint_num; ++index)
227236 {
@@ -477,32 +486,14 @@ CallbackReturn JointTrajectoryController::on_configure(const rclcpp_lifecycle::S
477486 // 2. velocity
478487 // 2. position [velocity, [acceleration]]
479488
480- // effort can't be combined with other interfaces
481- if (contains_interface_type (command_interface_types_, hardware_interface::HW_IF_EFFORT))
482- {
483- if (command_interface_types_.size () == 1 )
484- {
485- // TODO(anyone): This flag is not used for now
486- // There should be PID-approach used as in ROS1:
487- // https://github.com/ros-controls/ros_controllers/blob/noetic-devel/joint_trajectory_controller/include/joint_trajectory_controller/hardware_interface_adapter.h#L283
488- use_closed_loop_pid_adapter = true ;
489- // TODO(anyone): remove the next two lines when implemented
490- RCLCPP_ERROR (logger, " using 'effort' command interface alone is not yet implemented yet." );
491- return CallbackReturn::FAILURE;
492- }
493- else
494- {
495- RCLCPP_ERROR (logger, " 'effort' command interface has to be used alone." );
496- return CallbackReturn::FAILURE;
497- }
498- }
499-
500489 has_position_command_interface_ =
501490 contains_interface_type (command_interface_types_, hardware_interface::HW_IF_POSITION);
502491 has_velocity_command_interface_ =
503492 contains_interface_type (command_interface_types_, hardware_interface::HW_IF_VELOCITY);
504493 has_acceleration_command_interface_ =
505494 contains_interface_type (command_interface_types_, hardware_interface::HW_IF_ACCELERATION);
495+ has_effort_command_interface_ =
496+ contains_interface_type (command_interface_types_, hardware_interface::HW_IF_EFFORT);
506497
507498 if (has_velocity_command_interface_)
508499 {
@@ -530,8 +521,21 @@ CallbackReturn JointTrajectoryController::on_configure(const rclcpp_lifecycle::S
530521 return CallbackReturn::FAILURE;
531522 }
532523
533- // TODO(livanov93): change when other option is implemented
534- if (has_velocity_command_interface_ && use_closed_loop_pid_adapter)
524+ // effort can't be combined with other interfaces
525+ if (has_effort_command_interface_)
526+ {
527+ if (command_interface_types_.size () == 1 )
528+ {
529+ use_closed_loop_pid_adapter = true ;
530+ }
531+ else
532+ {
533+ RCLCPP_ERROR (logger, " 'effort' command interface has to be used alone." );
534+ return CallbackReturn::FAILURE;
535+ }
536+ }
537+
538+ if (use_closed_loop_pid_adapter)
535539 {
536540 size_t num_joints = joint_names_.size ();
537541 pids_.resize (num_joints);
@@ -593,7 +597,7 @@ CallbackReturn JointTrajectoryController::on_configure(const rclcpp_lifecycle::S
593597
594598 if (has_velocity_state_interface_)
595599 {
596- if (!contains_interface_type (state_interface_types_, hardware_interface::HW_IF_POSITION) )
600+ if (!has_position_state_interface_ )
597601 {
598602 RCLCPP_ERROR (
599603 logger,
@@ -602,13 +606,33 @@ CallbackReturn JointTrajectoryController::on_configure(const rclcpp_lifecycle::S
602606 return CallbackReturn::FAILURE;
603607 }
604608 }
605- else if (has_acceleration_state_interface_)
609+ else
606610 {
607- RCLCPP_ERROR (
608- logger,
609- " 'acceleration' state interface cannot be used if 'position' and 'velocity' "
610- " interfaces are not present." );
611- return CallbackReturn::FAILURE;
611+ if (has_acceleration_state_interface_)
612+ {
613+ RCLCPP_ERROR (
614+ logger,
615+ " 'acceleration' state interface cannot be used if 'position' and 'velocity' "
616+ " interfaces are not present." );
617+ return CallbackReturn::FAILURE;
618+ }
619+ if (has_velocity_command_interface_ && command_interface_types_.size () == 1 )
620+ {
621+ RCLCPP_ERROR (
622+ logger,
623+ " 'velocity' command interface can only be used alone if 'velocity' and "
624+ " 'position' state interfaces are present" );
625+ return CallbackReturn::FAILURE;
626+ }
627+ // effort is always used alone so no need for size check
628+ if (has_effort_command_interface_)
629+ {
630+ RCLCPP_ERROR (
631+ logger,
632+ " 'effort' command interface can only be used alone if 'velocity' and "
633+ " 'position' state interfaces are present" );
634+ return CallbackReturn::FAILURE;
635+ }
612636 }
613637
614638 auto get_interface_list = [](const std::vector<std::string> & interface_types) {
@@ -808,6 +832,11 @@ CallbackReturn JointTrajectoryController::on_deactivate(const rclcpp_lifecycle::
808832 {
809833 joint_command_interface_[1 ][index].get ().set_value (0.0 );
810834 }
835+
836+ if (has_effort_command_interface_)
837+ {
838+ joint_command_interface_[3 ][index].get ().set_value (0.0 );
839+ }
811840 }
812841
813842 for (size_t index = 0 ; index < allowed_interface_types_.size (); ++index)
@@ -845,6 +874,11 @@ bool JointTrajectoryController::reset()
845874 subscriber_is_active_ = false ;
846875 joint_command_subscriber_.reset ();
847876
877+ for (const auto & pid : pids_)
878+ {
879+ pid->reset ();
880+ }
881+
848882 // iterator has no default value
849883 // prev_traj_point_ptr_;
850884 traj_point_active_ptr_ = nullptr ;
0 commit comments