@@ -107,7 +107,7 @@ JointTrajectoryController::state_interface_configuration() const
107107}
108108
109109controller_interface::return_type JointTrajectoryController::update (
110- const rclcpp::Time & /* time*/ , const rclcpp::Duration & /* period*/ )
110+ const rclcpp::Time & /* time*/ , const rclcpp::Duration & period)
111111{
112112 if (get_state ().id () == lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE)
113113 {
@@ -197,7 +197,23 @@ controller_interface::return_type JointTrajectoryController::update(
197197 }
198198 if (has_velocity_command_interface_)
199199 {
200- assign_interface_from_point (joint_command_interface_[1 ], state_desired.velocities );
200+ if (!use_closed_loop_pid_adapter)
201+ {
202+ assign_interface_from_point (joint_command_interface_[1 ], state_desired.velocities );
203+ }
204+ else
205+ {
206+ // Update PIDs
207+ for (auto i = 0ul ; i < joint_num; ++i)
208+ {
209+ tmp_command_[i] = (state_desired.velocities [i] * ff_velocity_scale_[i]) +
210+ pids_[i]->computeCommand (
211+ state_desired.positions [i] - state_current.positions [i],
212+ state_desired.velocities [i] - state_current.velocities [i],
213+ (uint64_t )period.nanoseconds ());
214+ }
215+ assign_interface_from_point (joint_command_interface_[1 ], tmp_command_);
216+ }
201217 }
202218 if (has_acceleration_command_interface_)
203219 {
@@ -483,29 +499,19 @@ CallbackReturn JointTrajectoryController::on_configure(const rclcpp_lifecycle::S
483499 }
484500 }
485501
486- if (contains_interface_type (command_interface_types_, hardware_interface::HW_IF_POSITION))
487- {
488- has_position_command_interface_ = true ;
489- }
490- if (contains_interface_type (command_interface_types_, hardware_interface::HW_IF_VELOCITY))
491- {
492- has_velocity_command_interface_ = true ;
493- }
494- if (contains_interface_type (command_interface_types_, hardware_interface::HW_IF_ACCELERATION))
495- {
496- has_acceleration_command_interface_ = true ;
497- }
502+ has_position_command_interface_ =
503+ contains_interface_type (command_interface_types_, hardware_interface::HW_IF_POSITION);
504+ has_velocity_command_interface_ =
505+ contains_interface_type (command_interface_types_, hardware_interface::HW_IF_VELOCITY);
506+ has_acceleration_command_interface_ =
507+ contains_interface_type (command_interface_types_, hardware_interface::HW_IF_ACCELERATION);
498508
499509 if (has_velocity_command_interface_)
500510 {
501511 // if there is only velocity then use also PID adapter
502512 if (command_interface_types_.size () == 1 )
503513 {
504514 use_closed_loop_pid_adapter = true ;
505- // TODO(anyone): remove this when implemented
506- RCLCPP_ERROR (logger, " using 'velocity' command interface alone is not yet implemented yet." );
507- return CallbackReturn::FAILURE;
508- // if velocity interface can be used without position if multiple defined
509515 }
510516 else if (!has_position_command_interface_)
511517 {
@@ -526,6 +532,28 @@ CallbackReturn JointTrajectoryController::on_configure(const rclcpp_lifecycle::S
526532 return CallbackReturn::FAILURE;
527533 }
528534
535+ // TODO(livanov93): change when other option is implemented
536+ if (has_velocity_command_interface_ && use_closed_loop_pid_adapter)
537+ {
538+ size_t num_joints = joint_names_.size ();
539+ pids_.resize (num_joints);
540+ ff_velocity_scale_.resize (num_joints);
541+ tmp_command_.resize (num_joints, 0.0 );
542+
543+ // Init PID gains from ROS parameter server
544+ for (size_t i = 0 ; i < pids_.size (); ++i)
545+ {
546+ const std::string prefix = " gains." + joint_names_[i];
547+ const auto k_p = auto_declare<double >(prefix + " .p" , 0.0 );
548+ const auto k_i = auto_declare<double >(prefix + " .i" , 0.0 );
549+ const auto k_d = auto_declare<double >(prefix + " .d" , 0.0 );
550+ const auto i_clamp = auto_declare<double >(prefix + " .i_clamp" , 0.0 );
551+ ff_velocity_scale_[i] = auto_declare<double >(" ff_velocity_scale/" + joint_names_[i], 0.0 );
552+ // Initialize PID
553+ pids_[i] = std::make_shared<control_toolbox::Pid>(k_p, k_i, k_d, i_clamp, -i_clamp);
554+ }
555+ }
556+
529557 // Read always state interfaces from the parameter because they can be used
530558 // independently from the controller's type.
531559 // Specialized, child controllers should set its default value.
@@ -558,14 +586,12 @@ CallbackReturn JointTrajectoryController::on_configure(const rclcpp_lifecycle::S
558586 }
559587 }
560588
561- if (contains_interface_type (state_interface_types_, hardware_interface::HW_IF_VELOCITY))
562- {
563- has_velocity_state_interface_ = true ;
564- }
565- if (contains_interface_type (state_interface_types_, hardware_interface::HW_IF_ACCELERATION))
566- {
567- has_acceleration_state_interface_ = true ;
568- }
589+ has_position_state_interface_ =
590+ contains_interface_type (state_interface_types_, hardware_interface::HW_IF_POSITION);
591+ has_velocity_state_interface_ =
592+ contains_interface_type (state_interface_types_, hardware_interface::HW_IF_VELOCITY);
593+ has_acceleration_state_interface_ =
594+ contains_interface_type (state_interface_types_, hardware_interface::HW_IF_ACCELERATION);
569595
570596 if (has_velocity_state_interface_)
571597 {
@@ -774,8 +800,16 @@ CallbackReturn JointTrajectoryController::on_deactivate(const rclcpp_lifecycle::
774800 // TODO(anyone): How to halt when using effort commands?
775801 for (size_t index = 0 ; index < joint_names_.size (); ++index)
776802 {
777- joint_command_interface_[0 ][index].get ().set_value (
778- joint_command_interface_[0 ][index].get ().get_value ());
803+ if (has_position_command_interface_)
804+ {
805+ joint_command_interface_[0 ][index].get ().set_value (
806+ joint_command_interface_[0 ][index].get ().get_value ());
807+ }
808+
809+ if (has_velocity_command_interface_)
810+ {
811+ joint_command_interface_[1 ][index].get ().set_value (0.0 );
812+ }
779813 }
780814
781815 for (size_t index = 0 ; index < allowed_interface_types_.size (); ++index)
@@ -820,6 +854,12 @@ bool JointTrajectoryController::reset()
820854 traj_home_point_ptr_.reset ();
821855 traj_msg_home_ptr_.reset ();
822856
857+ // reset pids
858+ for (const auto & pid : pids_)
859+ {
860+ pid->reset ();
861+ }
862+
823863 return true ;
824864}
825865
@@ -965,7 +1005,19 @@ void JointTrajectoryController::fill_partial_goal(
9651005 for (auto & it : trajectory_msg->points )
9661006 {
9671007 // Assume hold position with 0 velocity and acceleration for missing joints
968- it.positions .push_back (joint_command_interface_[0 ][index].get ().get_value ());
1008+ if (!it.positions .empty ())
1009+ {
1010+ if (has_position_command_interface_)
1011+ {
1012+ // copy last command if cmd interface exists
1013+ it.positions .push_back (joint_command_interface_[0 ][index].get ().get_value ());
1014+ }
1015+ else if (has_position_state_interface_)
1016+ {
1017+ // copy current state if state interface exists
1018+ it.positions .push_back (joint_state_interface_[0 ][index].get ().get_value ());
1019+ }
1020+ }
9691021 if (!it.velocities .empty ())
9701022 {
9711023 it.velocities .push_back (0.0 );
0 commit comments