Skip to content

Commit 0ee15b4

Browse files
committed
new deep grasp generator stages uses action client
1 parent 80c8244 commit 0ee15b4

File tree

2 files changed

+165
-35
lines changed

2 files changed

+165
-35
lines changed

core/include/moveit/task_constructor/stages/action_base.h

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,23 @@ class ActionBase
6262
/**
6363
* @brief Constructor
6464
* @param action_name - action namespace
65-
* @param server_timeout - connection to server time out (0 is considered infinite timeout)
66-
* @param goal_timeout - goal to completed time out (0 is considered infinite timeout)
6765
* @param spin_thread - spins a thread to service this action's subscriptions
66+
* @param goal_timeout - goal to completed time out (0 is considered infinite timeout)
67+
* @param server_timeout - connection to server time out (0 is considered infinite timeout)
6868
* @details Initialize the action client and time out parameters
6969
*/
7070
ActionBase(const std::string &action_name,
71-
double server_timeout = 0.0,
72-
double goal_timeout = 0.0,
73-
bool spin_thread = true)
74-
: action_name_(action_name), server_timeout_(server_timeout), goal_timeout_(goal_timeout) {
71+
bool spin_thread,
72+
double goal_timeout,
73+
double server_timeout);
7574

76-
clientPtr_.reset(new actionlib::SimpleActionClient<ActionSpec>(action_name, spin_thread));
77-
}
78-
79-
// ActionBase(const std::string &action_name) : action_name_(action_name) {};
80-
// ActionBase() {}
75+
/**
76+
* @brief Constructor
77+
* @param action_name - action namespace
78+
* @param spin_thread - spins a thread to service this action's subscriptions
79+
* @details Initialize the action client and time out parameters to infinity
80+
*/
81+
ActionBase(const std::string &action_name, bool spin_thread);
8182

8283
/* @brief Destructor */
8384
virtual ~ActionBase() = default;
@@ -100,13 +101,33 @@ class ActionBase
100101
const ResultConstPtr &result) = 0;
101102

102103
protected:
103-
std::string action_name_;
104+
ros::NodeHandle nh_;
105+
std::string action_name_; // action name space
104106
std::unique_ptr<actionlib::SimpleActionClient<ActionSpec>> clientPtr_; // action client
105-
ActionGoal goal_; // goal message
106107
double server_timeout_, goal_timeout_; // connection and goal completed time out
107108
};
108109

109110

111+
template<class ActionSpec>
112+
ActionBase<ActionSpec>::ActionBase(const std::string &action_name,
113+
bool spin_thread,
114+
double goal_timeout,
115+
double server_timeout)
116+
: action_name_(action_name), server_timeout_(server_timeout), goal_timeout_(goal_timeout){
117+
clientPtr_.reset(new actionlib::SimpleActionClient<ActionSpec>(nh_, action_name_, spin_thread));
118+
119+
if (server_timeout_ < 0.0 || goal_timeout < 0.0){
120+
ROS_WARN("Timeouts cannot be negative");
121+
}
122+
}
123+
124+
125+
template<class ActionSpec>
126+
ActionBase<ActionSpec>::ActionBase(const std::string &action_name, bool spin_thread)
127+
: action_name_(action_name), server_timeout_(0.0), goal_timeout_(0.0){
128+
clientPtr_.reset(new actionlib::SimpleActionClient<ActionSpec>(nh_, action_name_, spin_thread));
129+
}
130+
110131
} // namespace stages
111132
} // namespace task_constructor
112133
} // namespace moveit

core/include/moveit/task_constructor/stages/gpd_generator.h

Lines changed: 131 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,38 +39,63 @@
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

5250
namespace moveit {
5351
namespace task_constructor {
5452
namespace 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+
*/
5759
template<class ActionSpec>
5860
class DeepGraspPose : public GeneratePose, ActionBase<ActionSpec>
5961
{
62+
63+
const std::string LOGNAME = "deep_grasp_generator";
64+
6065
private:
6166
typedef ActionBase<ActionSpec> ActionBaseT;
6267
ACTION_DEFINITION(ActionSpec);
6368

6469
public:
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+
95121
template<class ActionSpec>
96122
DeepGraspPose<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

112186
template<class ActionSpec>
113187
void 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
137213
template<class ActionSpec>
138214
void 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

191265
template<class ActionSpec>
192266
void 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

Comments
 (0)