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

moveit_servo: Fix segfault when publish_joint_velocities set to false and a joint is close to position limit #497

Merged
merged 5 commits into from Jun 25, 2021

Conversation

JafarAbdi
Copy link
Contributor

Description

moveit_servo is segfaulting when reaching limits if publish_joint_velocities set to false. the reason is in ServoCalcs::enforcePositionLimits we do access the velocities despite being an empty vector see

Checklist

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

@codecov
Copy link

codecov bot commented Jun 14, 2021

Codecov Report

Merging #497 (b7a1d8f) into main (eb2c8b9) will decrease coverage by 0.01%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #497      +/-   ##
==========================================
- Coverage   45.18%   45.17%   -0.00%     
==========================================
  Files         169      169              
  Lines       18732    18734       +2     
==========================================
  Hits         8462     8462              
- Misses      10270    10272       +2     
Impacted Files Coverage Δ
moveit_ros/moveit_servo/src/servo_calcs.cpp 0.00% <0.00%> (ø)

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 eb2c8b9...b7a1d8f. Read the comment docs.

Copy link
Member

@AndyZe AndyZe left a comment

Choose a reason for hiding this comment

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

This makes a lot of sense. Let me test it.

Copy link
Contributor

@schornakj schornakj left a comment

Choose a reason for hiding this comment

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

I tested this and it does stop Servo from segfaulting when I reach a joint position limit.

However, once I'm at a limit I'm not able to move back in the opposite direction or move any other joint in the robot. I get this warning message:

[moveit_servo.servo_calcs]: servo_server wrist_3_joint close to a position limit. Halting.

Seems like this is related to the conditional that sets halting = true. I think it should check if the commanded direction of rotation is still going towards the limit and still allow rotation if it goes away from the limit. Could that be resolved within the scope of this PR or does that require a lot of extra work?

@AndyZe
Copy link
Member

AndyZe commented Jun 15, 2021

Maybe we should always store joint position/vel/accel internally so we don't have to worry about this type of thing. Then publish_joint_velocities / publish_joint_positions / publish_joint_accelerations would only be applied to the outgoing message. Does that seem like a good path forward?

@AdamPettinger
Copy link
Contributor

I will test it too, but seems reasonable

I think it should check if the commanded direction of rotation is still going towards the limit and still allow rotation if it goes away from the limit. Could that be resolved within the scope of this PR or does that require a lot of extra work?

I think the original (seg faulting) code here was checking for this, so I would say the same behavior should be included in this PR

@JafarAbdi
Copy link
Contributor Author

I tested this and it does stop Servo from segfaulting when I reach a joint position limit.

However, once I'm at a limit I'm not able to move back in the opposite direction or move any other joint in the robot. I get this warning message:

[moveit_servo.servo_calcs]: servo_server wrist_3_joint close to a position limit. Halting.

Seems like this is related to the conditional that sets halting = true. I think it should check if the commanded direction of rotation is still going towards the limit and still allow rotation if it goes away from the limit. Could that be resolved within the scope of this PR or does that require a lot of extra work?

This also happens to me when the robot reaches collisions or joint limits and once it's there it will be stuck, but I think this's outside the scope of this PR since it requires changing the halting behavior

(joint_angle > (limits[0].max_position - parameters_->joint_limit_margin))))
const bool near_min_position =
parameters_->publish_joint_velocities ?
joint_trajectory.points[0].velocities[joint_idx] < 0 &&
Copy link
Member

Choose a reason for hiding this comment

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

If you change all the operator[] to at() it should help catch any future occurrences of this too.

@AndyZe
Copy link
Member

AndyZe commented Jun 15, 2021

This also happens to me when the robot reaches collisions or joint limits and once it's there it will be stuck, but I think this's outside the scope of this PR since it requires changing the halting behavior

However, there is a regression because it could reverse away from joint limits previously. Sorry, but I think we'll have to change the way this PR works. I'll make a pull request against your branch, @JafarAbdi.

@AdamPettinger
Copy link
Contributor

This also happens to me when the robot reaches collisions or joint limits and once it's there it will be stuck, but I think this's outside the scope of this PR since it requires changing the halting behavior

However, there is a regression because it could reverse away from joint limits previously. Sorry, but I think we'll have to change the way this PR works. I'll make a pull request against your branch, @JafarAbdi.

@AndyZe if it is not too late, I think a workable solution is to switch the order composeJointTrajMessage and enforcePositionLimits is called so that enforcePositionLimits works on a JointState and uses internal_joint_state_ which holds position and velocity information regardless of what should be published

@AndyZe
Copy link
Member

AndyZe commented Jun 15, 2021

@AdamPettinger do you mind making a PR? That sounds better than the way I did it.

@AdamPettinger
Copy link
Contributor

Yep! See JafarAbdi#13

Copy link
Contributor

@AdamPettinger AdamPettinger left a comment

Choose a reason for hiding this comment

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

Does joint limit checking probably the way it should have been all along 😅

Tested, and doesn't seg fault when publish_joint_velocities is false, and also allows backing away from a joint limit

Copy link
Contributor

@nbbrooks nbbrooks left a comment

Choose a reason for hiding this comment

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

+1 switch to at()

moveit_ros/moveit_servo/src/servo_calcs.cpp Show resolved Hide resolved
{
// Use the most recent robot joint state
if (original_joint_state_.name[c] == joint->getName())
if (joint_state.name[c] == joint->getName())
Copy link
Member

@AndyZe AndyZe Jun 24, 2021

Choose a reason for hiding this comment

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

It makes sense to use Servo's internal joint position here, rather than original_joint_state_. We do the same thing for velocity at L809 👍

@JafarAbdi JafarAbdi merged commit fb94e78 into moveit:main Jun 25, 2021
JafarAbdi added a commit to JafarAbdi/moveit2 that referenced this pull request Jun 28, 2021
… and a joint is close to position limit (moveit#497)

* moveit_servo: Fix segfault when publish_joint_velocities set to false and a joint is close to position limit

* Enforce joint position limits on internal joint state before making trajectory (#13)

* Use the input joint state to check bounds

Co-authored-by: AdamPettinger <adam.pettinger@utexas.edu>
JafarAbdi added a commit to JafarAbdi/moveit2 that referenced this pull request Jun 28, 2021
MikeWrock pushed a commit to MikeWrock/moveit2 that referenced this pull request Aug 15, 2022
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

6 participants