-
Notifications
You must be signed in to change notification settings - Fork 150
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
Make pregrasp pose optional in GenerateGraspPose #157
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally, I approve. However, I suggest keeping the unset default value,
requiring a user to explicitly set the pregrasp posture to an empty string if he wants to have the new behavior.
@@ -54,7 +54,7 @@ GenerateGraspPose::GenerateGraspPose(const std::string& name) : GeneratePose(nam | |||
p.declare<std::string>("object"); | |||
p.declare<double>("angle_delta", 0.1, "angular steps (rad)"); | |||
|
|||
p.declare<boost::any>("pregrasp", "pregrasp posture"); | |||
p.declare<boost::any>("pregrasp", std::string(""), "pregrasp posture"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep "unset" as default here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, is there a reason to declare the pregrasp
property as boost::any
rather than std::string
.? I see the only way it's being used is as std::string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good point. I think, the idea was to enable some message alternatively. But you are right, currently, we only use strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment below
@rhaschke I also thought about this, but I actually think that setting an empty string smells like a weird workaround and not like well-defined default behavior. I would suggest we don't check for an empty string, but only if the property is specified at all (checking the value of boost_any). The pregrasp pose property can actually be set to a moveit_msgs::RobotState, but this is not implemented and would result in a bad_any_cast exception if specified. Right now I'm fixing this by adding conditions that check for the property type. |
Hi @henningkayser, |
Going for a JointState message is fine. However, only the gripper joints should be considered. |
Wow, Easter vacations, and suddenly there is patches turning up. 😄
At the same time, if you add
I agree with Robert in that explicit is better than implicit in MTC.
I'd support the second and third approach.
This stage seeds the IK solver, so you conceptually don't know the full joint state at this point and shouldn't touch it. Filtering for joints of the eef is reasonable, possibly complaining if anything unexpected was found.
It is exposed in the interface states and read by All in all it is rather ridiculous how much discussion there is around this trivial stage that is meant as an example... |
7bc28f2
to
3143fd0
Compare
Still on the menu, right now this stage really works fine for basic use cases, though
Hmm, sounds a little bit like too much overhead for this feature
I don't really get why default behavior (that doesn't imply/change things based on some arbitrary assumptions but simply skips a feature) needs to be explicit. To me, 'pregrasp' and 'grasp' properties seem like optional features with certain use cases based on first pick pipeline designs. Couldn't we add the concept of optional properties that just don't do anything if not specified? These could also be checked on a property level without having to look into default values. Also, I just added support for JointState messages. If you both think setting an empty string is the way to go to disable the pregrasp pose, I can add that as well. |
* Make parameter optional (skip pregrasp if left empty) * Allow setting by JointState, filtered by eef joints * Check parameter validity + improved error messages
3143fd0
to
3c6dfe2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still on the menu, right now this stage really works fine for basic use cases, though
I agree and I don't really use or need the properties myself at the moment.
Still, they are required to fulfill the interface of SimpleGrasp
.
or, indeed, we explicitly make both optional, but also do not pass them on in the state properties if they are the default.
I don't really get why default behavior (that doesn't imply/change things based on some arbitrary assumptions but simply skips a feature) needs to be explicit. To me, 'pregrasp' and 'grasp' properties seem like optional features with certain use cases based on first pick pipeline designs. Couldn't we add the concept of optional properties that just don't do anything if not specified? These could also be checked on a property level without having to look into default values.
That's not quite what I wrote, but pretty much what I meant. I like your current patch, aside from the inline comments. I would only force "don't do anything" to include "not being passed on to other stages via InterfaceState
properties", thus the exposeTo
should be run conditionally too.
Could you please adjust handling the grasp
property similarly?
Also, I'm not sure the SimpleGrasp
container can handle JointState
s in the properties, but that's not overly important here as you provide a new feature.
if (!eef_jmg->getVariableDefaultPositions(pregrasp_name, m)) | ||
errors.push_back(*this, "pregrasp is set to unknown end effector pose: " + pregrasp_name); | ||
} else if (pregrasp_prop.type() == typeid(sensor_msgs::JointState)) { | ||
// check if the specified pregrasp pose is a valid named target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment does not make sense.
const auto& pregrasp_state = boost::any_cast<sensor_msgs::JointState>(pregrasp_prop); | ||
if (pregrasp_state.name.size() == pregrasp_state.position.size() && | ||
pregrasp_state.name.size() == pregrasp_state.velocity.size() && | ||
pregrasp_state.name.size() == pregrasp_state.effort.size()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you require velocity/effort to be set?
Positions suffice, though dynamics might be specified to define the dynamic grasp behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, the code only uses positions. Dynamic grasp behaviour comes into play if a trajectory would be specified. That's not the case.
if (pregrasp_state.name.size() == pregrasp_state.position.size() && | ||
pregrasp_state.name.size() == pregrasp_state.velocity.size() && | ||
pregrasp_state.name.size() == pregrasp_state.effort.size()) { | ||
// We only apply the joint state for for joints of the end effector |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// We only apply the joint state for for joints of the end effector | |
// We only apply the joint state for joints of the end effector |
if (eef_state.name.empty()) | ||
errors.push_back(*this, "pregrasp JointState doesn't contain joint values for end effector group"); | ||
else | ||
properties().set("pregrasp_state", eef_state); // Override property with filtered joint state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave it to Robert to comment on whether changing properties dynamically is a good idea.
I would consider adding a private member variable instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with me.
const auto& pregrasp_name = boost::any_cast<std::string>(pregrasp_prop); | ||
std::map<std::string, double> m; | ||
if (!eef_jmg->getVariableDefaultPositions(pregrasp_name, m)) | ||
errors.push_back(*this, "pregrasp is set to unknown end effector pose: " + pregrasp_name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you lookup the named target anyway, you might as well save the result for the compute call to avoid branching on the any
again there.
@henningkayser: What's the status of this PR? |
The pregrasp pose is now set as an empty string by default so that no pregrasp pose is applied. Instead, the stage will simply forward the current joint state of the gripper. There are several scenarios where it makes sense to let the pregrasp pose unspecified by default and to simply use the current state instead. For instance, a gripper could have different types of "open", depending on the monitored stage or could even use dynamically computed pregrasp poses matching to the size of the object. Also, an optional pregrasp pose enables to use this stage for suction grippers that don't have any predefined poses configured at all, so that it's easy to set up the same grasping pipeline for finger and suction grippers.