Skip to content

Use new handles API in ros2_controllers to fix deprecation warnings #1566

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

kumar-sanjeeev
Copy link
Contributor

@kumar-sanjeeev kumar-sanjeeev commented Mar 3, 2025

This PR applies the new API changes in the handles of ros2_control in following controllers in same fashion as #1565:

  • ackermann_steering_controller
  • bicycle_steering_controller
  • admittance_controller
  • effort_controllers
  • forward_command_controller
  • gpio_controllers
  • gripper_controllers
  • mecanum_drive_controller
  • parallel_gripper_controller
  • tricycle_controller
  • pid_controller
  • tricycle_steering_controller
  • mecum_driver_contoller
  • force_torque_sensor_broadcaster
  • steering_controllers_library
  • joint_state_broadcaster
  • position_controllers
  • joint_trajectory_controller (partial fixed)
  • diff_drive_controller

Copy link
Contributor

@christophfroehlich christophfroehlich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine, thanks!

@kumar-sanjeeev
Copy link
Contributor Author

Looks fine, thanks!

@christophfroehlich hi, one question - I have made progress on other controllers as well locally on my system. Can I push these changes into this PR as well (will update description), or should I wait for more reviews on current submitted PR ?

@christophfroehlich
Copy link
Contributor

@saikishor ?

Copy link
Member

@saikishor saikishor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes already look good to me. I just forgot to comment.
@kumar-sanjeeev yes, please proceed with other packages as well

@kumar-sanjeeev
Copy link
Contributor Author

@saikishor and @christophfroehlich , one question, would you like me to complete all the controller packages first, and then you would review them of all together? Or would you prefer to first provide feedback on the commits that have already been pushed in this PR?

@christophfroehlich
Copy link
Contributor

apply the changes to all of them please

@saikishor
Copy link
Member

Yes please

@christophfroehlich
Copy link
Contributor

@kumar-sanjeeev I haven't crosschecked your list, are there all controllers included now? (you might add a checklist of all controllers and just check the finished ones)

@kumar-sanjeeev
Copy link
Contributor Author

@kumar-sanjeeev I haven't crosschecked your list, are there all controllers included now? (you might add a checklist of all controllers and just check the finished ones)

hi @christophfroehlich
I am almost done, just a few controllers are pending. I will update the list as checklists (nice suggestion :) )

@christophfroehlich
Copy link
Contributor

hi @kumar-sanjeeev will you have time to finish this PR? otherwise, I'd like to review and merge the current status and fix he remaining ones in a future PR.

@kumar-sanjeeev
Copy link
Contributor Author

@christophfroehlich Sorry, I was a bit busy. give me time until next weekend, I’ll try to finish this PR by then, and you can review it afterward. If it’s urgent, feel free to start reviewing and leave comments where improvements are needed. I’ll address those along with the pending controllers that require fixes.

@bmagyar
Copy link
Member

bmagyar commented May 3, 2025

Thank you, @kumar-sanjeeev , please keep an eye on the current conflict too ;)

@kumar-sanjeeev
Copy link
Contributor Author

@christophfroehlich I tried to address most of the deprecation warnings across all controllers. You can start reviewing whenever you have time. Feel free to leave comments wherever you see room for improvement or a better approach. I’ll make the necessary changes based on your feedback.

Copy link
Contributor

mergify bot commented May 17, 2025

This pull request is in conflict. Could you fix it @kumar-sanjeeev?

Copy link
Contributor

@christophfroehlich christophfroehlich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for finishing this.
The first review from my side. Some simple changes (please apply them from the github UI so that the next review is faster), and some conceptional questions:

  • what should we do if setting a command fails? return or try to set the other commands? This is not consistent
  • for filling the publisher with data: I'd suggest to resume and just leave the message field untouched (should be the old vale then if the msg struct is pre-allocated). what do you think?

Comment on lines +61 to +65
if (!command_interface.set_value(0.0))
{
RCLCPP_WARN(get_node()->get_logger(), "Error while setting command interface value to 0.0");
}
return controller_interface::CallbackReturn::SUCCESS;
Copy link
Contributor

@christophfroehlich christophfroehlich May 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should go into the if branch, right?

Suggested change
if (!command_interface.set_value(0.0))
{
RCLCPP_WARN(get_node()->get_logger(), "Error while setting command interface value to 0.0");
}
return controller_interface::CallbackReturn::SUCCESS;
if (!command_interface.set_value(0.0))
{
RCLCPP_ERROR(get_node()->get_logger(), "Unable to set command interface value to 0.0");
return controller_interface::CallbackReturn::SUCCESS;
}

Comment on lines +151 to +152

return controller_interface::return_type::OK;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return controller_interface::return_type::OK;

command_interfaces_map_.at(full_command_interface_name)
.get()
.set_value(gpio_commands.interface_values[gpio_index].values[command_interface_index]);
if (!command_interfaces_map_.at(full_command_interface_name).get().set_value(command_value))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the other controllers, we return true if setting the command interfaces fails. why not here,too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. It should be the case here too. We have to return true or false and act accordingly

{
// copy last command if cmd interface exists
it.positions.push_back(joint_command_interface_[0][index].get().get_value());
it.positions.push_back(position_command_value_op.has_value());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a possibility that the value is nan, which we still should catch here?

get_node()->get_logger(),
"Unable to retrieve position command value of joint at index %zu", index);
}
if (has_position_command_interface_)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (has_position_command_interface_)
else if (has_position_command_interface_)

shouldn't this go in the else branch?

RCLCPP_DEBUG(
get_node()->get_logger(), "Unable to retrieve the state interface value for %s",
state_interfaces_[i].get_name().c_str());
return controller_interface::return_type::OK;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we really return here? if not, it will just use the old measured_state_values_ right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe with PID it is not a big issue?
Usually, in my use case, the reference comes at lower frequency and the PID runs at high freq trying to follow the commands

RCLCPP_DEBUG(
get_node()->get_logger(), "Unable to retrieve the command interface value for %s",
command_interfaces_[i].get_name().c_str());
return controller_interface::return_type::OK;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we really return here, or just publish the message without the output field?

{
RCLCPP_WARN(
logger, "Failed to set traction command %.3f for interface '%s' (index %zu).", value,
command_interfaces_[i].get_name().c_str(), i);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like above, should we abort and return if one command fails?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say return

{
RCLCPP_WARN(
logger, "Failed to set steering command %.3f for interface '%s' (index %zu).", value,
command_interfaces_[i].get_name().c_str(), i);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like above, should we abort and return if one command fails?

@@ -632,24 +653,58 @@ controller_interface::return_type SteeringControllersLibrary::update_and_write_c
{
if (params_.position_feedback)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like above, should we publish the message without the failing fields instead of aborting?

Copy link
Contributor

mergify bot commented May 17, 2025

This pull request is in conflict. Could you fix it @kumar-sanjeeev?

if (!command_interfaces_[index].set_value(data[index]))
{
RCLCPP_WARN(
logger, "Error while setting command interface value at index %zu: value = %f", index,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
logger, "Error while setting command interface value at index %zu: value = %f", index,
logger, "Unable to set the command interface value at index %zu: value = %f", index,

Comment on lines +362 to +363
get_node()->get_logger(), "Error while setting command for interface '%s' with value '%f'.",
full_command_interface_name.c_str(), command_value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
get_node()->get_logger(), "Error while setting command for interface '%s' with value '%f'.",
full_command_interface_name.c_str(), command_value);
get_node()->get_logger(), "Unable to set the command for interface '%s' with value '%f'.",
full_command_interface_name.c_str(), command_value);

command_interfaces_map_.at(full_command_interface_name)
.get()
.set_value(gpio_commands.interface_values[gpio_index].values[command_interface_index]);
if (!command_interfaces_map_.at(full_command_interface_name).get().set_value(command_value))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. It should be the case here too. We have to return true or false and act accordingly


if (!state_msg_interface_value_op.has_value())
{
RCLCPP_DEBUG(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RCLCPP_DEBUG(
RCLCPP_WARN(

const auto joint_state_interface_value_op = joint_interface[index].get().get_optional();
if (!joint_state_interface_value_op.has_value())
{
RCLCPP_DEBUG(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RCLCPP_DEBUG(
RCLCPP_WARN(

{
RCLCPP_WARN(
get_node()->get_logger(),
"Error while setting velocity command for traction joint to value: '%f'.", Ws_write);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Error while setting velocity command for traction joint to value: '%f'.", Ws_write);
"Unable to set the velocity command for traction joint to value: '%f'.", Ws_write);

{
RCLCPP_WARN(
get_node()->get_logger(),
"Error while setting position command for steering joint to value: '%f'.", alpha_write);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Error while setting position command for steering joint to value: '%f'.", alpha_write);
"Unable to set the position command for steering joint to value: '%f'.", alpha_write);

Comment on lines +461 to +467
"Error while setting velocity command for traction joint to value 0.0");
}
if (!steering_joint_[0].position_command.get().set_value(0.0))
{
RCLCPP_WARN(
get_node()->get_logger(),
"Error while setting position command for steering joint to value 0.0");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Error while setting velocity command for traction joint to value 0.0");
}
if (!steering_joint_[0].position_command.get().set_value(0.0))
{
RCLCPP_WARN(
get_node()->get_logger(),
"Error while setting position command for steering joint to value 0.0");
"Unable to set the velocity command for traction joint to value 0.0");
}
if (!steering_joint_[0].position_command.get().set_value(0.0))
{
RCLCPP_WARN(
get_node()->get_logger(),
"Unable to set the position command for steering joint to value 0.0");

!traction_right_wheel_value_op.has_value() || !traction_left_wheel_value_op.has_value() ||
!steering_position_op.value())
{
RCLCPP_DEBUG(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RCLCPP_DEBUG(
RCLCPP_WARN(

command_interface.set_value(0.0);
if (!command_interface.set_value(0.0))
{
RCLCPP_WARN(get_node()->get_logger(), "Error while setting command interface to value 0.0");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
RCLCPP_WARN(get_node()->get_logger(), "Error while setting command interface to value 0.0");
RCLCPP_WARN(get_node()->get_logger(), "Unable to set the command interface to value 0.0");

@kumar-sanjeeev
Copy link
Contributor Author

Thanks for finishing this. The first review from my side. Some simple changes (please apply them from the github UI so that the next review is faster), and some conceptional questions:

  • what should we do if setting a command fails? return or try to set the other commands? This is not consistent
  • for filling the publisher with data: I'd suggest to resume and just leave the message field untouched (should be the old vale then if the msg struct is pre-allocated). what do you think?

@christophfroehlich and @saikishor Thanks for comments. I’ll look at them over the weekend and get back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants