Skip to content
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

[Servo] Change planning frame to base frame of active joint subgroup #2515

Merged
merged 12 commits into from
Nov 13, 2023

Conversation

sea-bass
Copy link
Contributor

@sea-bass sea-bass commented Nov 8, 2023

Description

This PR seeks to solve an issue in which changing the active_subgroup parameter still enforces using the servo_params.planning_frame planning frame... which is not necessarily the correct frame for all subgroups.

So instead, we're grabbing the planning frame (for twist/pose commands) to always be the base frame of the IK solver and doing the frame conversions from there. This fixes the immediate issue, but the implementation leaves much to be desired.

@sea-bass sea-bass requested review from sjahr and eholum November 8, 2023 03:16
Comment on lines 376 to 379
const auto ik_solver = active_joint_model_group->getSolverInstance();
if (ik_solver)
{
const auto planning_frame = ik_solver->getBaseFrame();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a better way to get the base link of a joint model group without having to grab the IK solver like this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can't you do this?

const JointModel* root_joint_model = group->getJointModels().front();
const LinkModel* root_link_model = root_joint_model->getParentLinkModel();

But now I wonder if you rather need the IK solver base frame (i.e. your code as is), since the underlying IK solver could be working on a different frame, not necessarily the group root?
If that's the case, maybe create a getIKSolverBaseFrame() function that can be called here and below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

This raises a follow up question that, if these changes are the right thing for changing subgroups, can we actually get rid of the planning frame parameter and have servo always do its own internal conversions to active group's IK base frame?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm.. looking deeper into Servo I got more confused about what the 'planning frame' is, but also how this fix works, since the IK base frame for the manipulator group is the one tilted 45 deg. right? so I would expect this to still move the wrong way.
Another q: the command has a frame_id. Shouldn't that be all that is needed to move in the same frame (e.g. world), independently of the active group? Sorry I have more questions than answers!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You should have more questions than answers, I think there's a lot here that needs to be disentangled for clarity.

Basically, Servo has this rule that enforces that all commands passed into it are expressed w.r.t. a common frame -- this is the "planning frame" we speak of.

All we're trying to do, perhaps in an overly complex way, is the following:

  • Receive a Cartesian command w.r.t. some arbitrary frame ID
  • Convert it to a reference frame that agrees with the IK solver (this is our planning frame)
  • ???
  • Profit

Copy link
Contributor Author

@sea-bass sea-bass Nov 9, 2023

Choose a reason for hiding this comment

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

Hmm... I just saw some other piece of code that reminded me of the fact that a planning group can have multiple tip frames. So can we really get rid of moveit_params.ee_frame after all?

The other alternative, which is way more destructive, would be to modify the command message definitions for twist and pose tracking to contain both base and tip frames... which would basically require making custom messages for both instead of relying on existing geometry_msgs definitions.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can, at least the way it is now, because ee_frame doesn't seem to be used anywhere. The IK computation is done for ik_solver->getTipFrame(), so it will always use the first tip.
Longer term what about having Servo expose a /configure service, where the user could set the planning group and tip frame?

Copy link
Contributor Author

@sea-bass sea-bass Nov 9, 2023

Choose a reason for hiding this comment

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

Given all the struggles we've had trying to make sure that parameters stay consistent w.r.t. each other, I quite like the idea of dedicated services that touch these interrelated parameters like planning group + ee frame.

Also, having this configure service / method means that configuring can implicitly do the task of pausing servo, changing values, and then unpausing it.

Also, I guess to be fair this code was calling getTipFrame() already, and also there is an error logged when you call getTipFrame() on a planning group with multiple tips.

So maybe this is just a known limitation for now and we proceed as is?

Copy link
Member

Choose a reason for hiding this comment

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

A service to update the parameters might be a good idea b/c it would fix this issue: #2412

i.e. do the parameter validation in a callback in a different thread

Hate to change the API so drastically, so soon, though. Have to think carefully about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think servo has changed enough with the refactor since we kept running into limitations trying to keep the API as stable as possible with the old version. It might be beneficial to do all the big changes as soon as possible in hopes that we get to a somewhat more stable API before people actually start using this new version.

That said, we should try do all this in a way that minimizes our need to keep twiddling the interfaces going forward.

@sea-bass sea-bass changed the title Change planning frame to base of active subgroup [Servo] Change planning frame to base frame of active joint subgroup Nov 8, 2023
Copy link

codecov bot commented Nov 8, 2023

Codecov Report

Attention: 18 lines in your changes are missing coverage. Please review.

Comparison is base (4b73edb) 50.77% compared to head (0ad1d85) 50.82%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2515      +/-   ##
==========================================
+ Coverage   50.77%   50.82%   +0.05%     
==========================================
  Files         392      392              
  Lines       32170    32194      +24     
==========================================
+ Hits        16332    16358      +26     
+ Misses      15838    15836       -2     
Files Coverage Δ
...oveit_ros/moveit_servo/tests/servo_cpp_fixture.hpp 100.00% <100.00%> (ø)
...oveit_ros/moveit_servo/tests/servo_ros_fixture.hpp 93.23% <100.00%> (ø)
moveit_ros/moveit_servo/tests/test_integration.cpp 100.00% <100.00%> (ø)
moveit_ros/moveit_servo/src/utils/common.cpp 84.71% <83.34%> (-0.29%) ⬇️
moveit_ros/moveit_servo/src/utils/command.cpp 70.28% <62.50%> (ø)
moveit_ros/moveit_servo/src/servo.cpp 67.89% <77.97%> (+1.80%) ⬆️

... and 1 file with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@AndyZe AndyZe self-requested a review November 8, 2023 15:06
@sea-bass sea-bass marked this pull request as ready for review November 8, 2023 16:54
Copy link
Contributor

@marioprats marioprats left a comment

Choose a reason for hiding this comment

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

This looks good to me. A couple of minor comments that can be done in follow-up changes too, since they are not really related to this PR changes.

moveit_ros/moveit_servo/demos/cpp_interface/demo_pose.cpp Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/include/moveit_servo/servo.hpp Outdated Show resolved Hide resolved
* @param group_name The currently active joint group name.
* @return The IK solver base frame, if one exists, otherwise std::nullopt.
*/
std::optional<std::string> getIKSolverBaseFrame(const moveit::core::RobotStatePtr& robot_state,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we avoid the pointer here and below and just do const moveit::core::RobotState &robot_state?

Copy link
Contributor Author

@sea-bass sea-bass Nov 10, 2023

Choose a reason for hiding this comment

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

I think the robot state which is extracted from

moveit::core::RobotStatePtr CurrentStateMonitor::getCurrentState() const

already returns in pointer form, so is it fine to keep as is? I don't particularly want to dereference what's already there.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's fine if this is only used in this context. If we ever put it somewhere more general I think we should just take the const&.
shared_ptr is viral, it easily spreads everywhere. If this takes a shared_ptr, it can't really can't be used unless you have a shared_ptr already. Whereas if this takes a const&, you can call it directly with a RobotState object, but also with a shared_ptr or unique_ptr by derefencing, so it's more usable.

Copy link
Contributor

@sjahr sjahr left a comment

Choose a reason for hiding this comment

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

Nice work! Most of my comments are around more error messages and documentations. Besides that I think it is good to go 👍

moveit_ros/moveit_servo/src/servo.cpp Show resolved Hide resolved
moveit_ros/moveit_servo/src/servo.cpp Show resolved Hide resolved
moveit_ros/moveit_servo/src/servo.cpp Show resolved Hide resolved
moveit_ros/moveit_servo/src/servo.cpp Show resolved Hide resolved
moveit_ros/moveit_servo/src/servo.cpp Show resolved Hide resolved
moveit_ros/moveit_servo/src/servo.cpp Show resolved Hide resolved
moveit_ros/moveit_servo/src/utils/command.cpp Show resolved Hide resolved
@sea-bass sea-bass requested a review from sjahr November 13, 2023 15:51
@sea-bass
Copy link
Contributor Author

@AndyZe we're cutting a release tomorrow so I'm going to merge this in now. If you have any follow-on comments related to this PR, let's do a new issue/PR and take it from there?

@sea-bass sea-bass merged commit 2487b24 into main Nov 13, 2023
14 of 15 checks passed
@sea-bass sea-bass deleted the fix-servo-subgroup-cmds branch November 13, 2023 20:19
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.

None yet

5 participants