Skip to content

Fix orientation of subframe offset before applying to motion plans#2890

Closed
riv-tnoble wants to merge 15 commits intomoveit:masterfrom
rivelinrobotics:bugfix/pilz-subframe-fix-pr
Closed

Fix orientation of subframe offset before applying to motion plans#2890
riv-tnoble wants to merge 15 commits intomoveit:masterfrom
rivelinrobotics:bugfix/pilz-subframe-fix-pr

Conversation

@riv-tnoble
Copy link
Copy Markdown
Contributor

@riv-tnoble riv-tnoble commented Sep 29, 2021

Description

This PR fixes #2879 by reorienting the subframe offset applied to a goal pose in the PTP planner, so that it is applied in the correct direction. It also adds the same offset computation to LIN and CIRC motions, allowing them to work with subframes.

The video below demonstrates the fix by showing that the goal point planned to by pilz PTP is now the same as OMPL.

pilz_subframes_fix.mp4

Checklist

  • Required by CI: Code is auto formatted using clang-format
  • Extend the tutorials / documentation reference (Not applicable)
  • Document API changes relevant to the user in the MIGRATION.md notes (Not applicable)
  • Create tests, which fail without this PR reference
  • Include a screenshot if changing a GUI (Not applicable)
  • While waiting for someone to review your request, please help review another open pull request to support the maintainers

@codecov
Copy link
Copy Markdown

codecov bot commented Sep 29, 2021

Codecov Report

Merging #2890 (a58b15c) into master (a0ee202) will increase coverage by 0.04%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2890      +/-   ##
==========================================
+ Coverage   61.31%   61.35%   +0.04%     
==========================================
  Files         373      373              
  Lines       31742    31747       +5     
==========================================
+ Hits        19461    19476      +15     
+ Misses      12281    12271      -10     
Impacted Files Coverage Δ
...strial_motion_planner/src/trajectory_functions.cpp 100.00% <100.00%> (ø)
...l_motion_planner/src/trajectory_generator_circ.cpp 100.00% <100.00%> (ø)
...al_motion_planner/src/trajectory_generator_lin.cpp 100.00% <100.00%> (ø)
...al_motion_planner/src/trajectory_generator_ptp.cpp 98.92% <100.00%> (-0.07%) ⬇️
...raint_samplers/src/default_constraint_samplers.cpp 79.23% <0.00%> (+0.30%) ⬆️
...meterization/work_space/pose_model_state_space.cpp 83.65% <0.00%> (+0.63%) ⬆️
...g_scene_interface/src/planning_scene_interface.cpp 49.72% <0.00%> (+1.16%) ⬆️
.../ompl_interface/src/detail/constrained_sampler.cpp 59.46% <0.00%> (+16.22%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a0ee202...a58b15c. Read the comment docs.

@simonschmeisser
Copy link
Copy Markdown
Contributor

Could those calculations be moved to a common location? Are they maybe even useful outside of pilz?

@riv-rbush
Copy link
Copy Markdown

@simonschmeisser While they are probably useful, those calculations are a specific fix for this pilz bug and this bug only. I gave @aa-tom the mandate to fix this bug and not add enhancements to the MoveIt! codebase. We'd appreciate some help from the MoveIt! community if your suggestion is desired, otherwise it would be good to merge this before the 1.1.6 MoveIt! release.

@riv-rbush
Copy link
Copy Markdown

Also fixes #2884

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

Agree that it'd be nice to make this code common if possible. The most reasonable place seems like the ResolveConstraintFrames plugin, which calculates the subframe offsets before the plan request reaches the planner. I have a couple of concerns though:

  • I'm not too familiar with the plugin, so would want to make sure that there isn't a specific reason why the offsets aren't already being oriented using the goal pose there. @rhaschke could you weigh in here? I think you originally developed the ResolveConstraintFrames plugin?

  • I think making the change in the plugin could have unintended effects in other planners. OMPL was never broken, which suggests to me that there's already some kind of offset computation going on in there. I'm worried that, without a thorough investigation of which planners would need to change in response to putting the offset computation in the plugin, we could end up breaking more plans than we fix. Maybe worth its own issue though?

Copy link
Copy Markdown
Contributor

@jschleicher jschleicher left a comment

Choose a reason for hiding this comment

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

Thank you very much for your investigation!

Other planners rely on the KinematicConstraint classes, which are probably designed for sampling. This is a fundamental differnce of OMPL - here we just use a single constraint. I would prefer a more general approach, but currently am not aware of a simple solution.

To avoid code-duplication, you could still move the offset part into trajectory_functions.cpp or similar.

Note that for a circle, you probably also have to add the offset to the circ_path_point (interim or center): https://github.com/ros-planning/moveit/blob/049be73b8343d67ffde400fed9ed4c387c6ea9e5/moveit_planners/pilz_industrial_motion_planner/src/trajectory_generator_circ.cpp#L183

Comment on lines +242 to +249
Eigen::Vector3d offset_in_world;
tf2::fromMsg(req.goal_constraints.at(0).position_constraints.at(0).target_point_offset, offset_in_world);
Eigen::Quaterniond goal_orientation;
tf2::fromMsg(req.goal_constraints.at(0).orientation_constraints.at(0).orientation, goal_orientation);
Eigen::Vector3d offset_in_goal = goal_orientation * offset_in_world;
p.x -= offset_in_goal[0];
p.y -= offset_in_goal[1];
p.z -= offset_in_goal[2];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would a calculation directly with Eigen types give the same results? Would look a bit more readable to me:

Suggested change
Eigen::Vector3d offset_in_world;
tf2::fromMsg(req.goal_constraints.at(0).position_constraints.at(0).target_point_offset, offset_in_world);
Eigen::Quaterniond goal_orientation;
tf2::fromMsg(req.goal_constraints.at(0).orientation_constraints.at(0).orientation, goal_orientation);
Eigen::Vector3d offset_in_goal = goal_orientation * offset_in_world;
p.x -= offset_in_goal[0];
p.y -= offset_in_goal[1];
p.z -= offset_in_goal[2];
geometry_msgs::Pose pose;
pose.position =
req.goal_constraints.at(0).position_constraints.at(0).constraint_region.primitive_poses.at(0).position;
pose.orientation = req.goal_constraints.at(0).orientation_constraints.at(0).orientation;
normalizeQuaternion(pose.orientation);
Eigen::Isometry3d pose_eigen;
tf2::fromMsg(pose, pose_eigen);
Eigen::Isometry3d offset_in_world;
tf2::fromMsg(req.goal_constraints.at(0).position_constraints.at(0).target_point_offset, offset_in_world);
pose_eigen.linear() -= offset_in_world * pose_eigen.rotation();

Copy link
Copy Markdown
Contributor Author

@riv-tnoble riv-tnoble Sep 30, 2021

Choose a reason for hiding this comment

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

Thanks for the advice! Will get those tasks done tomorrow:

  • Move common offset transformation into trajectory_functions.cpp
  • Apply offset to center for CIRC motions
  • Tidy up Eigen computations

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

@jschleicher @rhaschke @v4hn Any ideas why the build might be failing?

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

Looks like the Windows build failure is the same as this #2892 (comment)

Unsure why so many tests would be failing provided they aren't all using offsets and aren't checking for specific end poses

@v4hn
Copy link
Copy Markdown
Contributor

v4hn commented Oct 4, 2021 via email

* @param constraint
* @return
*/
Eigen::Isometry3d getConstraintPose(moveit_msgs::Constraints constraint);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Eigen::Isometry3d getConstraintPose(moveit_msgs::Constraints constraint);
Eigen::Isometry3d getConstraintPose(const moveit_msgs::Constraints& constraint);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done 👍

@jschleicher
Copy link
Copy Markdown
Contributor

@aa-tom You can run the tests locally with more output using for example rostest --text pilz_industrial_motion_planner integrationtest_command_planning_frankaemika_panda.test
Which gives an output of

[ INFO] [1633345214.152003125]: Received new planning service request...
[ INFO] [1633345214.152090320]: The timeout for planning must be positive (0.000000 specified). Assuming one second instead.
[ INFO] [1633345214.152116846]: Generating CIRC trajectory...
[ERROR] [1633345214.152365149]: Exception caught: 'vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)'

so maybe some check for empty constraint lists got lost?

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

Thanks. Will run the tests locally and take a look this afternoon

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

Sorry for the delay! I believe I've fixed the tests now (locally, at least). The issue was caused by trying to access the goal's position constraints when applying the offset to the circle interim/center as some tests use goals with no position constraints. I have a couple of questions I was hoping you could answer @jschleicher :

  • Is is normal for a goal to have no position constraints? My best guess is that the goal can be specified entirely in joint constraints instead?
  • Assuming the above is true, I'm guessing there's no way we can apply an offset, since it's associated with a position constraint to begin with. Is that correct?

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

riv-tnoble commented Oct 21, 2021

Looks like the Windows build failed. Would it be be possible to rerun the pipeline too?
Scratch that, needed to sync with master anyway 😁

@v4hn
Copy link
Copy Markdown
Contributor

v4hn commented Oct 21, 2021

Is is normal for a goal to have no position constraints? My best guess is that the goal can be specified entirely in joint constraints instead?

It's not normal, but it's supported throughout the pipeline and should not break anything.
But yes, in that case you can't (and don't need to) associate a Cartesian offset with the goal.

Looks like the Windows build failed

Yes, please ignore it, RoboStack has trouble again.

@riv-tnoble riv-tnoble requested a review from v4hn October 21, 2021 14:22
Copy link
Copy Markdown
Contributor

@jschleicher jschleicher left a comment

Choose a reason for hiding this comment

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

Great to see this progress! Approving 👍

Copy link
Copy Markdown
Contributor

@v4hn v4hn left a comment

Choose a reason for hiding this comment

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

I do believe you fixed the issue with this patch at your end, but do we actually have a test for your use setup? Not saying I insist on writing one to merge this fix.

Please consider my inline feedback though.

const geometry_msgs::Quaternion& orientation)
{
geometry_msgs::Pose pose;
pose.position = constraint.position_constraints.front().constraint_region.primitive_poses.front().position;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is the only line where you use constraint and passing the whole constraint object makes the other two parameters redundant in two out of three calls (Is the CIRC call passing path_constraints actually correct?)

Please either pass only a Constraints message *and possibly create one for the CIRC call) or change the first parameter to a Vector3, so you can unpack the Constraints message before the call.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I addressed this feedback in rivelinrobotics#5. Please merge this and provide unit tests. Thanks!

@v4hn v4hn mentioned this pull request Oct 22, 2021
@riv-tnoble
Copy link
Copy Markdown
Contributor Author

riv-tnoble commented Oct 22, 2021

I do believe you fixed the issue with this patch at your end, but do we actually have a test for your use setup? Not saying I insist on writing one to merge this fix.

No automated tests currently, but I'm happy to write them. I'm thinking perhaps a unit test for each planner inspecting the MotionPlanInfo object and an integration test for each verifying the motion succeeds would be sufficient?

This is the only line where you use constraint and passing the whole constraint object makes the other two parameters redundant in two out of three calls (Is the CIRC call passing path_constraints actually correct?)

I believe the CIRC call is correct as we want to apply the target offset to the interim / center point in addition to the goal point, though I've only tested the fix manually using PTP, so an automated test would be good in that regard.

Please either pass only a Constraints message *and possibly create one for the CIRC call) or change the first parameter to a Vector3, so you can unpack the Constraints message before the call.

Shall do. I'll change the parameter to Vector3

  • Change getConstraintPose() to accept Vector3
  • Write unit test for PTP planner
  • ... for LIN planner
  • ... for CIRC planner
  • Write component test for PTP planner
  • ... for LIN planner
  • ... for CIRC planner

@riv-tnoble riv-tnoble changed the title Fix orientation of subframe offset before applying to PTP motions. Ad… Fix orientation of subframe offset before applying to motion plans Oct 25, 2021
@rhaschke
Copy link
Copy Markdown
Contributor

rhaschke commented Nov 2, 2021

@rivelin-tom, what is your progress on #2890 (comment)? This PR is currently blocking the next Noetic release as your colleague? asked for merging this before: #2890 (comment)

@rhaschke
Copy link
Copy Markdown
Contributor

rhaschke commented Nov 5, 2021

Ping @rivelin-tom.

rhaschke added a commit to ubi-agni/moveit that referenced this pull request Nov 6, 2021
Fix moveit#2879 by reorienting the subframe offset applied to a goal pose in the PTP planner,
so that it is applied in the correct direction.
Also add the same offset computation to LIN and CIRC generators,
thus allowing them to work with subframes.

Co-authored-by: Robert Haschke <rhaschke@users.noreply.github.com>
@simonschmeisser
Copy link
Copy Markdown
Contributor

@rhaschke should this be closed since you merged it manually?

@rhaschke
Copy link
Copy Markdown
Contributor

rhaschke commented Nov 6, 2021

Should this be closed since you merged it manually?

No, I'm still waiting for unit tests to be added... Unfortunately, there was no activity from @rivelin-tom since 15 days.
I took the time to fix the code as suggested, merge the bug fix, and thus unblock the release.

@riv-rbush
Copy link
Copy Markdown

@rhaschke Apologies for the delay but @rivelin-tom has had to implement some features and enhancements for us. We've not forgotten about it, just had some urgent and critical work to get out the way first.

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

@rhaschke Thanks a bunch for getting it ready for the release and apologies for the delay. I'm super busy at the moment, so it'll be a little while before I'm able to pick this back up and write the tests. I do intend to write them!

@gautz
Copy link
Copy Markdown
Contributor

gautz commented Nov 16, 2021

Is this replaced by e30c6fa?
Should this PR be further extended to correctly transform the CIRC interim frame when setIKframe() is set to an attached object subframe in MTC ? See the issue described here
.

see also moveit/moveit_task_constructor#191 and moveit/moveit_task_constructor#304

@v4hn
Copy link
Copy Markdown
Contributor

v4hn commented Dec 15, 2021

@rivelin-tom Is it still realistic to wait for your tests here? I know you want to do them, but you are obviously busy with other things.

Should this PR be further extended

No, feel free to open separate PRs if you have patches.

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

@v4hn I think it'd be best to close this off for now to avoid delaying longer. I believe it was already merged with master as part of the 1.1.6 release? Happy for this PR to simply be closed if that's the case

@rhaschke
Copy link
Copy Markdown
Contributor

Yes, the fix was already merged. However, this PR is still open as a reminder that you, @rivelin-tom, promised to provide some unit tests. Of course, you can close here and open a new PR for those tests.

@riv-tnoble
Copy link
Copy Markdown
Contributor Author

Sorry, was away for Christmas. I will do that, then. Thanks for the help implementing the changes 👍

@riv-tnoble riv-tnoble closed this Jan 4, 2022
@riv-tnoble riv-tnoble deleted the bugfix/pilz-subframe-fix-pr branch November 9, 2023 08:11
rhaschke added a commit that referenced this pull request Nov 11, 2023
rhaschke added a commit to ubi-agni/moveit that referenced this pull request Nov 11, 2023
rhaschke added a commit that referenced this pull request Nov 12, 2023
…3523)

* Revert consideration of link offset in start/goal poses (introduced in #2890)
* Consider link offset in IK computation instead
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.

PILZ Planning with attached collision object subframe

7 participants