pr2_gripper_sensor_action.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 // Author: Stu Glaser (modified by Joe Romano from pr2_gripper_action)
31 
32 #include "ros/ros.h"
33 
35 #include <pr2_controllers_msgs/JointControllerState.h>
36 #include <pr2_controllers_msgs/Pr2GripperCommand.h>
37 #include <pr2_controllers_msgs/Pr2GripperCommandAction.h>
38 #include <std_srvs/Empty.h>
39 
41 {
42 private:
45 
46 public:
48  node_(n),
49  action_server_(node_, "gripper_action",
50  boost::bind(&Pr2GripperAction::goalCB, this, _1),
51  boost::bind(&Pr2GripperAction::cancelCB, this, _1)),
52  has_active_goal_(false)
53  {
54  ros::NodeHandle pn("~");
55 
56  //pn.param("goal_threshold", goal_threshold_, 0.01);
57  pn.param("stall_velocity_threshold", stall_velocity_threshold_, 1e-6);
58  pn.param("stall_timeout", stall_timeout_, 0.1);
59 
60  // we will listen for messages on "state" and send messages on "command"
62  node_.advertise<pr2_controllers_msgs::Pr2GripperCommand>("command", 1);
65 
67  }
68 
70  {
74  }
75 
76 private:
77 
83 
85  GoalHandle active_goal_;
87 
93 
94  void watchdog(const ros::TimerEvent &e)
95  {
96  ros::Time now = ros::Time::now();
97 
98  // Aborts the active goal if the controller does not appear to be active.
99  if (has_active_goal_)
100  {
101  bool should_abort = false;
103  {
104  should_abort = true;
105  ROS_WARN("Aborting goal because we have never heard a controller state message.");
106  }
107  else if ((now - last_controller_state_->header.stamp) > ros::Duration(5.0))
108  {
109  should_abort = true;
110  ROS_WARN("Aborting goal because we haven't heard from the controller in %.3lf seconds",
111  (now - last_controller_state_->header.stamp).toSec());
112  }
113 
114  if (should_abort)
115  {
116  // Marks the current goal as aborted.
117  active_goal_.setAborted();
118  has_active_goal_ = false;
119  }
120  }
121  }
122 
123  void goalCB(GoalHandle gh)
124  {
125  // Cancels the currently active goal.
126  if (has_active_goal_)
127  {
128  // Marks the current goal as canceled.
129  active_goal_.setCanceled();
130  has_active_goal_ = false;
131  }
132 
133  gh.setAccepted();
134  active_goal_ = gh;
135  has_active_goal_ = true;
136  goal_received_ = ros::Time::now();
137  min_error_seen_ = 1e10;
138 
139  // Sends the command along to the controller.
140  pub_controller_command_.publish(active_goal_.getGoal()->command);
141  last_movement_time_ = ros::Time::now();
142  }
143 
144  void cancelCB(GoalHandle gh)
145  {
146  if (active_goal_ == gh)
147  {
148  /*
149  // Stops the controller.
150  if (last_controller_state_)
151  {
152  pr2_controllers_msgs::Pr2GripperCommand stop;
153  stop.position = last_controller_state_->process_value;
154  stop.max_effort = 0.0;
155  pub_controller_command_.publish(stop);
156  }
157  */
158  // stop the real-time motor control
159  std_srvs::Empty::Request req;
160  std_srvs::Empty::Response resp;
161  if(ros::service::exists("stop_motor_output",true))
162  {
163  ROS_INFO("Stopping Motor Output");
164  ros::service::call("stop_motor_output",req,resp);
165  }
166 
167  // Marks the current goal as canceled.
168  active_goal_.setCanceled();
169  has_active_goal_ = false;
170  }
171  }
172 
173 
174 
175  pr2_controllers_msgs::JointControllerStateConstPtr last_controller_state_;
176  void controllerStateCB(const pr2_controllers_msgs::JointControllerStateConstPtr &msg)
177  {
178  last_controller_state_ = msg;
179  ros::Time now = ros::Time::now();
180 
181  if (!has_active_goal_)
182  return;
183 
184  // grab the goal threshold off the param server
185  if(!node_.getParam("position_servo_position_tolerance", goal_threshold_))
186  ROS_ERROR("No position_servo_position_tolerance given in namespace: '%s')", node_.getNamespace().c_str());
187 
188 
189  // Ensures that the controller is tracking my setpoint.
190  if (fabs(msg->set_point - active_goal_.getGoal()->command.position) > stall_velocity_threshold_)
191  {
192  if (now - goal_received_ < ros::Duration(1.0))
193  {
194  return;
195  }
196  else
197  {
198  ROS_ERROR("Cancelling goal: Controller is trying to achieve a different setpoint.");
199  active_goal_.setCanceled();
200  has_active_goal_ = false;
201  }
202  }
203 
204 
205  pr2_controllers_msgs::Pr2GripperCommandFeedback feedback;
206  feedback.position = msg->process_value;
207  feedback.effort = msg->command;
208  feedback.reached_goal = false;
209  feedback.stalled = false;
210 
211  pr2_controllers_msgs::Pr2GripperCommandResult result;
212  result.position = msg->process_value;
213  result.effort = msg->command;
214  result.reached_goal = false;
215  result.stalled = false;
216 
217  // check if we've reached the goal
218  if (fabs(msg->process_value - active_goal_.getGoal()->command.position) < goal_threshold_)
219  {
220  feedback.reached_goal = true;
221 
222  result.reached_goal = true;
223  active_goal_.setSucceeded(result);
224  has_active_goal_ = false;
225  }
226  else
227  {
228  // Determines if the gripper has stalled.
229  if (fabs(msg->process_value_dot) > stall_velocity_threshold_)
230  {
231  last_movement_time_ = ros::Time::now();
232  }
233  else if ((ros::Time::now() - last_movement_time_).toSec() > stall_timeout_ &&
234  active_goal_.getGoal()->command.max_effort != 0.0)
235  {
236  feedback.stalled = true;
237 
238  result.stalled = true;
239  active_goal_.setAborted(result);
240  has_active_goal_ = false;
241  }
242  }
243  active_goal_.publishFeedback(feedback);
244  }
245 };
246 
247 
248 int main(int argc, char** argv)
249 {
250  ros::init(argc, argv, "gripper_action_node");
251  ros::NodeHandle node;
252  Pr2GripperAction jte(node);
253 
254  ros::spin();
255 
256  return 0;
257 }
void publishFeedback(const Feedback &feedback)
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
bool call(const std::string &service_name, MReq &req, MRes &res)
void stop()
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void cancelCB(GoalHandle gh)
boost::shared_ptr< const Goal > getGoal() const
Pr2GripperAction(ros::NodeHandle &n)
#define ROS_WARN(...)
void setCanceled(const Result &result=Result(), const std::string &text=std::string(""))
ROSCPP_DECL void spin(Spinner &spinner)
void setAccepted(const std::string &text=std::string(""))
void goalCB(GoalHandle gh)
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
ros::Subscriber sub_controller_state_
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
const std::string & getNamespace() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
actionlib::ActionServer< pr2_controllers_msgs::Pr2GripperCommandAction > GAS
void controllerStateCB(const pr2_controllers_msgs::JointControllerStateConstPtr &msg)
pr2_controllers_msgs::JointControllerStateConstPtr last_controller_state_
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
void watchdog(const ros::TimerEvent &e)
bool getParam(const std::string &key, std::string &s) const
static Time now()
ros::Publisher pub_controller_command_
ROSCPP_DECL bool exists(const std::string &service_name, bool print_failure_reason)
resp
#define ROS_ERROR(...)
int main(int argc, char **argv)


pr2_gripper_sensor_action
Author(s): Joe Romano
autogenerated on Wed Apr 1 2020 03:58:26