3939#include < moveit/task_constructor/stages/generate_pose.h>
4040#include < moveit/task_constructor/stages/action_base.h>
4141#include < moveit/task_constructor/storage.h>
42+ #include < moveit/task_constructor/marker_tools.h>
43+ #include < rviz_marker_tools/marker_creation.h>
4244#include < moveit/planning_scene/planning_scene.h>
4345
44- #include < Eigen/Geometry>
45- #include < eigen_conversions/eigen_msg.h>
46-
4746#include < memory>
48-
49- #include < moveit_task_constructor_msgs/GenerateDeepGraspPoseAction.h>
47+ #include < functional>
5048
5149
5250namespace moveit {
5351namespace task_constructor {
5452namespace stages {
5553
56-
54+ /* *
55+ * @brief Generate grasp candidates using deep learning approaches
56+ * @param ActionSpec - action message (action message name + "ACTION")
57+ * @details Interfaces with a deep learning based grasp library using a action client
58+ */
5759template <class ActionSpec >
5860class DeepGraspPose : public GeneratePose , ActionBase<ActionSpec>
5961{
62+
63+ const std::string LOGNAME = " deep_grasp_generator" ;
64+
6065private:
6166 typedef ActionBase<ActionSpec> ActionBaseT;
6267 ACTION_DEFINITION (ActionSpec);
6368
6469public:
70+ /* *
71+ * @brief Constructor
72+ * @param action_name - action namespace
73+ * @param stage_name - name of stage
74+ * @param goal_timeout - goal to completed time out (0 is considered infinite timeout)
75+ * @param server_timeout - connection to server time out (0 is considered infinite timeout)
76+ * @details Initialize the client and connect to server
77+ */
6578 DeepGraspPose (const std::string& action_name,
66- const std::string& stage_name = " generate grasp pose" );
79+ const std::string& stage_name = " generate grasp pose" ,
80+ double goal_timeout = 0.0 ,
81+ double server_timeout = 0.0 );
82+
83+ /* *
84+ * @brief Composes the action goal and sends to server
85+ */
86+ void composeGoal ();
87+
88+ /* *
89+ * @brief Monitors status of action goal
90+ * @return true if grasp candidates are received within (optinal) timeout
91+ * @details This is a blocking call. It will wait until either grasp candidates
92+ * are received or the (optinal) timeout has been reached.
93+ */
94+ bool monitorGoal ();
6795
6896 void activeCallback () override ;
69-
7097 void feedbackCallback (const FeedbackConstPtr &feedback) override ;
71-
72- void doneCallback (const actionlib::SimpleClientGoalState& state,
73- const ResultConstPtr &result) override ;
98+ void doneCallback (const actionlib::SimpleClientGoalState& state, const ResultConstPtr &result) override ;
7499
75100 void init (const core::RobotModelConstPtr& robot_model) override ;
76101 void compute () override ;
@@ -92,10 +117,16 @@ class DeepGraspPose : public GeneratePose, ActionBase<ActionSpec>
92117 std::vector<double > costs_;
93118};
94119
120+
95121template <class ActionSpec >
96122DeepGraspPose<ActionSpec>::DeepGraspPose(const std::string& action_name,
97- const std::string& stage_name)
98- : GeneratePose(stage_name), ActionBaseT(action_name), found_candidates_(false ) {
123+ const std::string& stage_name,
124+ double goal_timeout,
125+ double server_timeout)
126+ : GeneratePose(stage_name),
127+ ActionBaseT (action_name, false , goal_timeout, server_timeout),
128+ found_candidates_(false ){
129+
99130 auto & p = properties ();
100131 p.declare <std::string>(" eef" , " name of end-effector" );
101132 p.declare <std::string>(" object" );
@@ -104,15 +135,58 @@ DeepGraspPose<ActionSpec>::DeepGraspPose(const std::string& action_name,
104135 p.declare <boost::any>(" pregrasp" , " pregrasp posture" );
105136 p.declare <boost::any>(" grasp" , " grasp posture" );
106137
107- ROS_INFO ( " Waiting for connection to grasp generation action server..." );
138+ ROS_INFO_NAMED (LOGNAME, " Waiting for connection to grasp generation action server..." );
108139 ActionBaseT::clientPtr_->waitForServer (ros::Duration (ActionBaseT::server_timeout_));
140+ ROS_INFO_NAMED (LOGNAME, " Connected to server" );
141+ }
142+
143+
144+ template <class ActionSpec >
145+ void DeepGraspPose<ActionSpec>::composeGoal(){
146+ Goal goal;
147+ goal.action_name = ActionBaseT::action_name_;
148+ ActionBaseT::clientPtr_->sendGoal (goal,
149+ std::bind (&DeepGraspPose<ActionSpec>::doneCallback, this , std::placeholders::_1, std::placeholders::_2),
150+ std::bind (&DeepGraspPose<ActionSpec>::activeCallback, this ),
151+ std::bind (&DeepGraspPose<ActionSpec>::feedbackCallback, this , std::placeholders::_1));
152+
153+ ROS_INFO_NAMED (LOGNAME, " Goal sent to server: %s" , ActionBaseT::action_name_.c_str ());
154+ }
155+
156+
157+ template <class ActionSpec >
158+ bool DeepGraspPose<ActionSpec>::monitorGoal(){
159+
160+ // monitor timeout
161+ bool monitor_timeout = ActionBaseT::goal_timeout_ > std::numeric_limits<double >::epsilon () ? true : false ;
162+
163+ double curr_time = ros::Time::now ().toSec ();
164+ double timeout_time = curr_time + ActionBaseT::goal_timeout_;
165+
166+ while (ActionBaseT::nh_.ok ())
167+ {
168+ ros::spinOnce ();
169+
170+ if (found_candidates_){
171+ break ;
172+ }
173+
174+ curr_time = ros::Time::now ().toSec ();
175+ if (curr_time > timeout_time && monitor_timeout){
176+ ActionBaseT::clientPtr_->cancelGoal ();
177+ ROS_ERROR_NAMED (LOGNAME, " Grasp pose generator time out reached" );
178+ return false ;
179+ }
180+ }
181+
182+ return true ;
109183}
110184
111185
112186template <class ActionSpec >
113187void DeepGraspPose<ActionSpec>::activeCallback(){
114- ROS_INFO ( " Generate grasp goal now active " );
115- // found_candidates_ = false;
188+ ROS_INFO_NAMED (LOGNAME, " Generate grasp goal now active" );
189+ found_candidates_ = false ;
116190}
117191
118192
@@ -122,9 +196,11 @@ void DeepGraspPose<ActionSpec>::feedbackCallback(const FeedbackConstPtr &feedbac
122196
123197 // each candidate should have a cost
124198 if (feedback->grasp_candidates .size () != feedback->costs .size ()){
125- ROS_ERROR ( " Invalid input: each grasp candidate needs an associated cost" );
199+ ROS_ERROR_NAMED (LOGNAME, " Invalid input: each grasp candidate needs an associated cost" );
126200 }
127201 else {
202+ ROS_INFO_NAMED (LOGNAME, " Grasp generated feedback received" );
203+
128204 grasp_candidates_.resize (feedback->grasp_candidates .size ());
129205 costs_.resize (feedback->costs .size ());
130206
@@ -137,14 +213,12 @@ void DeepGraspPose<ActionSpec>::feedbackCallback(const FeedbackConstPtr &feedbac
137213template <class ActionSpec >
138214void DeepGraspPose<ActionSpec>::doneCallback(const actionlib::SimpleClientGoalState& state,
139215 const ResultConstPtr &result){
140- // TODO: add completion timeout
141-
142216 if (state == actionlib::SimpleClientGoalState::SUCCEEDED){
143217 found_candidates_ = true ;
144- ROS_INFO ( " Successfully found grasp candidates (result): %s" , result->grasp_state .c_str ());
218+ ROS_INFO_NAMED (LOGNAME, " Found grasp candidates (result): %s" , result->grasp_state .c_str ());
145219 }
146220 else {
147- ROS_WARN ( " No grasp candidates found (state): %s" , ActionBaseT::clientPtr_->getState ().toString ().c_str ());
221+ ROS_ERROR_NAMED (LOGNAME, " No grasp candidates found (state): %s" , ActionBaseT::clientPtr_->getState ().toString ().c_str ());
148222 }
149223}
150224
@@ -190,8 +264,43 @@ void DeepGraspPose<ActionSpec>::init(const core::RobotModelConstPtr& robot_model
190264
191265template <class ActionSpec >
192266void DeepGraspPose<ActionSpec>::compute(){
267+ if (upstream_solutions_.empty ()){
268+ return ;
269+ }
193270
271+ planning_scene::PlanningScenePtr scene = upstream_solutions_.pop ()->end ()->scene ()->diff ();
194272
273+ // set end effector pose
274+ const auto & props = properties ();
275+ const std::string& eef = props.get <std::string>(" eef" );
276+ const moveit::core::JointModelGroup* jmg = scene->getRobotModel ()->getEndEffector (eef);
277+
278+ robot_state::RobotState& robot_state = scene->getCurrentStateNonConst ();
279+ robot_state.setToDefaultValues (jmg, props.get <std::string>(" pregrasp" ));
280+
281+
282+ // compose/send goal
283+ composeGoal ();
284+
285+ // monitor feedback/results
286+ // blocking function untill timeout reached or results received
287+ if (monitorGoal ()){
288+ for (unsigned int i = 0 ; i < grasp_candidates_.size (); i++)
289+ {
290+ InterfaceState state (scene);
291+ state.properties ().set (" target_pose" , grasp_candidates_.at (i));
292+ props.exposeTo (state.properties (), { " pregrasp" , " grasp" });
293+
294+ SubTrajectory trajectory;
295+ trajectory.setCost (costs_.at (i));
296+ trajectory.setComment (std::to_string (i));
297+
298+ // add frame at target pose
299+ rviz_marker_tools::appendFrame (trajectory.markers (), grasp_candidates_.at (i), 0.1 , " grasp frame" );
300+
301+ spawn (std::move (state), std::move (trajectory));
302+ }
303+ }
195304}
196305
197306
@@ -210,7 +319,7 @@ void DeepGraspPose<ActionSpec>::onNewSolution(const SolutionBase& s){
210319 solution.setComment (msg);
211320 spawn (std::move (state), std::move (solution));
212321 } else {
213- ROS_WARN_STREAM_NAMED (" GenerateGraspPose " , msg);
322+ ROS_WARN_STREAM_NAMED (LOGNAME , msg);
214323 }
215324 return ;
216325 }
0 commit comments