parallel_gripper.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2014, Fetch Robotics Inc.
5  * Copyright (c) 2014, Unbounded Robotics Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Fetch Robotics Inc. nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 // Author: Michael Ferguson
37 
40 
42 
43 namespace robot_controllers
44 {
45 
46 int ParallelGripperController::init(ros::NodeHandle& nh, ControllerManager* manager)
47 {
48  // We absolutely need access to the controller manager
49  if (!manager)
50  {
51  initialized_ = false;
52  return -1;
53  }
54 
55  Controller::init(nh, manager);
56  manager_ = manager;
57 
58  // Setup Joints */
59  std::string l_name, r_name;
60  nh.param<std::string>("l_gripper_joint", l_name, "l_gripper_finger_joint");
61  nh.param<std::string>("r_gripper_joint", r_name, "r_gripper_finger_joint");
62 
63  left_ = manager_->getJointHandle(l_name);
64  right_ = manager_->getJointHandle(r_name);
65 
66  // Checking to see if Joint Handles exists
67  if (!left_)
68  {
69  ROS_ERROR_NAMED("ParallelGripperController",
70  "Unable to retreive joint (%s), Namespace: %s/l_gripper_joint",
71  l_name.c_str(), nh.getNamespace().c_str());
72  return -1;
73  }
74 
75  if (!right_)
76  {
77  ROS_ERROR_NAMED("ParallelGripperController",
78  "Unable to retreive joint (%s), Namespace: %s/r_gripper_joint",
79  r_name.c_str(), nh.getNamespace().c_str());
80  return -1;
81  }
82 
83  // Start action server
84  server_.reset(new server_t(nh, "",
85  boost::bind(&ParallelGripperController::executeCb, this, _1),
86  false));
87  server_->start();
88 
89  // Get Params
90  nh.param<double>("max_position", max_position_, 0.1);
91  nh.param<double>("max_effort", max_effort_, 10.0);
92 
93  // PID controller for centering the gripper
94  if (centering_pid_.init(ros::NodeHandle(nh, "centering")))
95  {
96  use_centering_controller_ = true;
97  }
98 
99  // Set default to max
100  goal_ = max_position_;
101  effort_ = max_effort_;
102 
103  initialized_ = true;
104  return 0;
105 }
106 
107 bool ParallelGripperController::start()
108 {
109  if (!initialized_)
110  {
111  ROS_ERROR_NAMED("ParallelGripperController",
112  "Unable to start, not initialized.");
113  return false;
114  }
115 
116  if (!server_->isActive())
117  {
118  ROS_ERROR_NAMED("ParallelGripperController",
119  "Unable to start, action server is not active.");
120  return false;
121  }
122 
123  return true;
124 }
125 
126 bool ParallelGripperController::stop(bool force)
127 {
128  if (!initialized_)
129  return true;
130 
131  if (server_->isActive())
132  {
133  if (force)
134  {
135  // Shut down the action
136  server_->setPreempted();
137  return true;
138  }
139 
140  // Do not abort unless forced
141  return false;
142  }
143 
144  // Just holding position, go ahead and stop us
145  return true;
146 }
147 
148 bool ParallelGripperController::reset()
149 {
150  // Nothing to do here
151  return true;
152 }
153 
154 void ParallelGripperController::update(const ros::Time& now, const ros::Duration& dt)
155 {
156  if (!initialized_)
157  return;
158 
159  if (use_centering_controller_)
160  {
161  double position = left_->getPosition() + right_->getPosition();
162  double effort = fabs(effort_);
163  if (goal_ < position)
164  {
165  effort = -effort;
166  }
167 
168  double offset = centering_pid_.update(left_->getPosition() - right_->getPosition(), dt.toSec());
169 
170  left_->setEffort(effort - offset);
171  right_->setEffort(effort + offset);
172  }
173  else
174  {
175  left_->setPosition(goal_/2.0, 0, effort_);
176  right_->setPosition(goal_/2.0, 0, effort_);
177  }
178 }
179 
180 void ParallelGripperController::executeCb(const control_msgs::GripperCommandGoalConstPtr& goal)
181 {
182  control_msgs::GripperCommandFeedback feedback;
183  control_msgs::GripperCommandResult result;
184 
185  if (!initialized_)
186  {
187  server_->setAborted(result, "Controller is not initialized.");
188  return;
189  }
190 
191  if (manager_->requestStart(getName()) != 0)
192  {
193  server_->setAborted(result, "Cannot execute, unable to start controller.");
194  ROS_ERROR_NAMED("ParallelGripperController",
195  "Cannot execute, unable to start controller.");
196  return;
197  }
198 
199  // Effort of 0.0 means use max
200  if (goal->command.max_effort <= 0.0 || goal->command.max_effort > max_effort_)
201  {
202  effort_ = max_effort_;
203  }
204  else
205  {
206  effort_ = goal->command.max_effort;
207  }
208 
209  // Set goal position
210  if (goal->command.position > max_position_)
211  {
212  goal_ = max_position_;
213  }
214  else if (goal->command.position < 0.0)
215  {
216  goal_ = 0.0;
217  }
218  else
219  {
220  goal_ = goal->command.position;
221  }
222 
223  // Track position/time for stall detection
224  float last_position = left_->getPosition() + right_->getPosition();
225  ros::Time last_position_time = ros::Time::now();
226 
227  ros::Rate r(50);
228  while (true)
229  {
230  // Abort detection
231  if (server_->isPreemptRequested() || !ros::ok())
232  {
233  ROS_DEBUG_NAMED("ParallelGripperController", "Command preempted.");
234  server_->setPreempted();
235  break;
236  }
237 
238  // Publish feedback before possibly completing
239  feedback.position = left_->getPosition() + right_->getPosition();
240  feedback.effort = left_->getEffort() + right_->getEffort();
241  feedback.reached_goal = false;
242  feedback.stalled = false;
243  server_->publishFeedback(feedback);
244 
245  // Goal detection
246  if (fabs(feedback.position - goal->command.position) < 0.002)
247  {
248  result.position = feedback.position;
249  result.effort = feedback.effort;
250  result.reached_goal = true;
251  result.stalled = false;
252  ROS_DEBUG_NAMED("ParallelGripperController", "Command Succeeded.");
253  server_->setSucceeded(result);
254  return;
255  }
256 
257  // Stall detection
258  if (fabs(feedback.position - last_position) > 0.005)
259  {
260  last_position = feedback.position;
261  last_position_time = ros::Time::now();
262  }
263  else
264  {
265  if (ros::Time::now() - last_position_time > ros::Duration(2.0))
266  {
267  result.position = feedback.position;
268  result.effort = feedback.effort;
269  result.reached_goal = false;
270  result.stalled = true;
271  ROS_DEBUG_NAMED("ParallelGripperController", "Gripper stalled, but succeeding.");
272  server_->setSucceeded(result);
273  return;
274  }
275  }
276 
277  r.sleep();
278  }
279 }
280 
281 std::vector<std::string> ParallelGripperController::getCommandedNames()
282 {
283  std::vector<std::string> names;
284  names.push_back(left_->getName());
285  names.push_back(right_->getName());
286  return names;
287 }
288 
289 std::vector<std::string> ParallelGripperController::getClaimedNames()
290 {
291  // Claimed == commanded.
292  return getCommandedNames();
293 }
294 
295 } // namespace robot_controllers
result
std::string getName(void *handle)
#define ROS_DEBUG_NAMED(name,...)
Controller for a parallel jaw gripper, is really only intended for use in simulation.
bool param(const std::string &param_name, T &param_val, const T &default_val) const
ROSCPP_DECL bool ok()
const std::string & getNamespace() const
bool sleep()
#define ROS_ERROR_NAMED(name,...)
static Time now()
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)


robot_controllers
Author(s): Michael Ferguson
autogenerated on Sun Sep 27 2020 03:22:39