Make pregrasp pose optional in GenerateGraspPose#157
Make pregrasp pose optional in GenerateGraspPose#157henningkayser wants to merge 2 commits intomoveit:masterfrom
Conversation
rhaschke
left a comment
There was a problem hiding this comment.
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.
| 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.
Keep "unset" as default here?
There was a problem hiding this comment.
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.
Very good point. I think, the idea was to enable some message alternatively. But you are right, currently, we only use strings.
@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
v4hn
left a comment
There was a problem hiding this comment.
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 JointStates 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.
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.
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.
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.
| // 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.
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.
| 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.
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.