gripper_controller.h
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2008, Willow Garage, 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 the Willow Garage 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  * \author Joe Romano
36  *********************************************************************/
37 //@author Joe Romano
38 //@email joeromano@gmail.com
39 //@brief gripperController.h - class to read data from gripper sensor
40 // data helper classes and make the gripper take action on it
41 // through a variety of different control modes.
42 
49 
50 #ifndef _GRIPPER_CONTROLLER
51 #define _GRIPPER_CONTROLLER
52 
53 
55 
56  public:
57  // functions
58  gripperController(pr2_mechanism_model::JointState* joint_state_, pressureObserver* pressure_observer_, accelerationObserver* acceleration_observer_); // ctor
59  ~gripperController(); // default dtor
60  bool velocityServo(double desiredVel);
61  bool positionServo(double desiredPos, double desiredVel); // servo to a desired position
62  void updateData(); // update gripper state info (should run at 1khz)
63  bool initializeGripper(); //
64  bool forceServo2(double desired_Force); // servo gripper on pressure sensor force
65  bool grabObject(double close_speed, int contactsDesired); // look for object contacts on each finger
66  bool slipServo2(); // servo gripper on slip information from psensors
67  bool forceRampTo(double force, double duration); // ramp the current force to a specific value over time
68  bool place(int placeConditions,double acc_trigger, double slip_trigger); // method to look for contact and return true when detected
69 
70 
71  // externally modified variables
72  double max_effort;
76 
77  // externally accessed variables
78  bool slip_flag;
82 
83  //variables
84  //PerformanceCounter counter;
85  double vel_integral; // velocity integral for force control
87  double lpVelocity; // a low-passsed version of our velocity
88  double accThresh;
90  double positionOpen; // the 'open' position of gripper
91  double positionClosed; // the 'closed' position of gripper
92  double positionCurrent; // current gripper position
93  double positionDropped; // the position below which we consider things dropped
94  double servoForce; // the force we are trying to servo to
95  double objectForce; // the force found to be best to hold the current object
96  double positionContact; // the last position we saw contact at
97  double forceContact; // the force seen at contact (average)
98  double forceContact_l, forceContact_r; // the force seen on l/r fingers at contact
100 
101  // storage of our gripper state information
104 
105  double kP; // proportional gain of position controller
106  double kD; // derivative gain of position controller
107  double dt; // time expired this current timestep
108  double coulomb; // coulomb term for position controller
109 
110  pr2_mechanism_model::JointState* jointState; // a copy of our joint handle
111  pressureObserver* myPressureObserver; // a copy of our pres. obsrv. handle
112  accelerationObserver* myAccelerationObserver; // a copy of our acc. obsrv. handle
113 
114  bool firstRamp; // flag to indicate the first iteration of forceRampTo
115  double ramp_start_time; // time that forceRampTo started
116  double ramp_start_force; // force that forceRampTo started on
117 
118  private:
119  double initialPosition; // the starting position when this class was called
120  double time_prev, time_cur; // the prev/current time of our control loop
121 };
122 
123 
124 
126 {
127  // update our timing information
129  //counter.StopCounter();
130  time_cur = ros::Time::now().toSec();//counter.GetElapsedTime();
131 
132 
133  // move old variables to gripperState_prev
137 
138  // get new variables and store them in _now
143 
144  // store a convenient double for our current position
146 
147  // call our pressure sensor and accelerometer update algorithm
150 }
151 
152 
153 // method to close the hand and stop when dual contacts are encountered
154 bool gripperController::grabObject(double close_speed, int contactsDesired)
155 {
156  // if the pressure sensors have not yet detected dual impacts
157  if( !(myPressureObserver->graspContact(contactsDesired)) )
158  {
159  velocityServo(close_speed); // keep closing
160  return false;
161  }
162  // if we have detected dual impacts
163  else
164  {
165  // store the contact position and force
173  return true;
174  }
175 }
176 
177 
178 // method to open the hand when gripper transience is encountered
179 bool gripperController::place(int placeConditions, double acc_trigger, double slip_trigger)
180 {
181  bool accContact = myAccelerationObserver->checkPlaceContact(acc_trigger);
182  bool slipContact = myPressureObserver->checkPlaceContact(slip_trigger);
183  int sideImpact = myPressureObserver->checkSideImpact(0.2);
184  bool returnValue = false;
185 
186  if(placeConditions == 0 )
187  returnValue = accContact || (sideImpact != -1);
188  else if(placeConditions == 1 )
189  returnValue = accContact && slipContact;
190  else if(placeConditions == 2 )
191  returnValue = accContact || slipContact || (sideImpact != -1);
192  else if(placeConditions == 3)
193  returnValue = slipContact;
194  else if(placeConditions == 4)
195  returnValue = accContact;
196 
197 
198  return returnValue;
199 }
200 
201 
202 // servo slip
204 {
205  // note: with higher forceservo gains .0005 seems good.
206  double slipIncrementPercent = 0.002; // .001 worked nicely. .005 seemed a little agressive // actually percent/100. Since we are "oversampling" the real percentage we are increasing is this *41
207 
209  {
210  servoForce = servoForce + servoForce*slipIncrementPercent;
211  slip_flag = true;
212  }
213  else
214  slip_flag = false;
215 
216  // check for our force limit
218  {
219  force_limit_flag = true;
221  }
222  else
223  force_limit_flag = false;
224 
226 
227  // if the pressure ever drops to less than 0.1N less than our lightest applicable force
228  // or the gripper ends up closed, consider the object f
230  {
231  dropped_flag = true;
232  positionMarker = positionCurrent; // reset our position marker since the object was dropped
233  jointState->commanded_effort_ = -100.0; // close as hard as possible
234  }
235  else
236  dropped_flag = false;
237 
238 
239 
240  return true;
241 }
242 
243 
244 
245 
246 // method to servo the robot to a desired finger force value
247 bool gripperController::forceServo2(double desired_Force)
248 {
249  // do not allow the force controller to apply anything weaker than forceLightest
250  if(desired_Force > -(myPressureObserver->forceLightest))
251  desired_Force = -(myPressureObserver->forceLightest);
252 
253  // store the force we are currently trying to servo to
254  servoForce = desired_Force;
255 
256  // figure out which finger is seeing less force, and use that value
258 
259  // our gain for the force controller
260  double kP_f = 0.0008;//was 0.0000003; // was .0006
261  // if we are trying to close more use a strong gain
262  if( desired_Force-minFingerForce < 0)
263  kP_f = 0.0016; // .008 breaks eggs (spikes too hard). .003 seems good
264 
265  // calculate our force components
266  double v_force = -kP_f * (minFingerForce - desired_Force);
267 
268  // limit our velocity values to limit extremely high velocities on large force descrepancies
269  double v_bound = 0.50; // set a limit on the speed (m/s?) .005 worked .015 worked .035 worked .075 looked good
270  if(v_force < -v_bound)
271  v_force = -v_bound;
272  else if(v_force > v_bound)
273  v_force = v_bound;
274 
275 
276  // limit our integral (position) term
277  double p_bound = 0.03;
278  if( (((vel_integral-positionCurrent) > p_bound) && v_force*dt > 0) ||
279  (((vel_integral-positionCurrent) < -p_bound) && v_force*dt < 0) )
280  {}
281  else
282  {
283  // integrate the velocity over time
284  vel_integral += v_force * dt;
285  }
286 
287  // assign our position to be the integrated velocity value
288  double p_force = vel_integral;
289 
290  // zero closes gripper
291  positionServo(p_force,v_force);
292 
293  // return true if force achieved within some tolerance
294  if(fabs(minFingerForce-desired_Force) < force_servo_force_tolerance)
295  return true;
296  else
297  return false;
298 }
299 
300 
301 // method to ramp the current force to a specific value over a defined timeperiod
302 bool gripperController::forceRampTo(double force, double duration)
303 {
304  // if it is the first time entering this forceRampTo function
305  if(firstRamp)
306  {
307  // store the time and force we started at
310  firstRamp = false;
311  return false;
312  }
313 
314  // if the time of the ramp has not expired ramp down linearly
315  else if(time_cur-ramp_start_time < duration)
316  {
318  return false;
319  }
320 
321  return true;
322 
323 }
324 
325 
326 bool gripperController::velocityServo(double desiredVel)
327 {
328  // integrate the velocity over time
329  vel_integral_vcontrol += desiredVel * dt;
330  return positionServo(vel_integral_vcontrol, desiredVel);
331 }
332 
333 
334 // method to position servo the robot to a desired position. non-blocking. requires continuous polling to accurately update torque information
335 // @input desiredPos - the desired position to move to.
336 // @input desireVel - the desiredVelocity to try to move at
337 // @output - true if the desired position has been achieved (within some threshold), false if it has not yet been achieved
338 bool gripperController::positionServo(double desiredPos, double desiredVel)
339 {
340 
341  // NOTE: This is coded so that it only stops the robot from closing too much, not opening
342  // check if we are using a deformation limit
343  // and if we are violating that limit, and trying to violate it more
346  if( (positionMarker_limit >= 0.0) && (positionCurrent < positionMarker-positionMarker_limit) )
347  deformation_limit_flag = true;
348  else
349  deformation_limit_flag = false;
350 
351 
352  // calculate our force components
353  double pos_force = -kP * (gripper_state_now_position - desiredPos);
354  double vel_force = -kD * (gripper_state_now_velocity - desiredVel);
355 
356  // deal with coulomb friction in the gripper
357  if (desiredVel > 0.0) vel_force += coulomb;
358  else if (desiredVel < 0.0) vel_force -= coulomb;
359 
360  double fbk_force = pos_force + vel_force;
361 
362  // ensure we do not exceed the max_effort value
363  if (max_effort >= 0.0)
364  fbk_force = std::max(-max_effort, std::min(fbk_force, max_effort));
365 
366  // ensure that we do not exceed our deformation limit
367  jointState->commanded_effort_ = fbk_force;
368 
369  return false;
370 }
371 
372 
373 // method returns true when initialization complete
375 {
376  return true;
377 }
378 
379 // ctor
381 {
382  // store our gripper joint state handle
383  jointState = joint_state_;
384 
385  // store our pressure observer
386  myPressureObserver = pressure_observer_;
387 
388  // store our acceleration observer
389  myAccelerationObserver = acceleration_observer_;
390 
391  // setup our position controller gain values
392  kP = 20000; // 20000
393  kD = 5000; // 5000
394  coulomb = 7;
395 
396  // some default's for our variables
397  positionOpen = 0.1; // param server stuff?
398  positionClosed = 0.0; // param server stuff?
399  vel_integral = 0.0;
400  positionDropped = 0.003; // 3mm
401  servoForce = 0.0;
402  accThresh = 4.0;
403 
404  // instatiate our digital filter
405  // 1st order butterworth, 5 hz lp
406  float b_vfilt[] = { 0.0155, 0.0155};
407  float a_vfilt[] = {1.0, -0.9691};
408  velocityLPFilt = new digitalFilter(1, true,b_vfilt,a_vfilt);
409 
410  // our timestep time we expect
411  dt = 0.001; // 1 ms
412 
413  // store the initial position
415 
416  // set the firstInitialize state to true
417  firstRamp = true;
418 
419 }
420 
421 
422 // destructor
424 {}
425 
426 
427 #endif // _GRIPPER_CONTROLLER
double force_servo_force_tolerance
bool checkSlip(double slip_motion_limit=0.007, double slip_force_limit=0.18)
bool checkPlaceContact(double dF)
digitalFilter * velocityLPFilt
double padForce_left_cur_nonbiased
bool graspContact(int contactsDesired)
bool positionServo(double desiredPos, double desiredVel)
bool checkPlaceContact(double dAcc)
bool grabObject(double close_speed, int contactsDesired)
pr2_mechanism_model::JointState * jointState
double gripper_state_now_measured_effort
float getNextFilteredValue(float u_current)
bool place(int placeConditions, double acc_trigger, double slip_trigger)
bool forceServo2(double desired_Force)
double gripper_state_prev_measured_effort
gripperController(pr2_mechanism_model::JointState *joint_state_, pressureObserver *pressure_observer_, accelerationObserver *acceleration_observer_)
accelerationObserver * myAccelerationObserver
bool forceRampTo(double force, double duration)
static Time now()
int checkSideImpact(double dF)
double padForce_right_cur_nonbiased
bool velocityServo(double desiredVel)
pressureObserver * myPressureObserver


pr2_gripper_sensor_controller
Author(s): Joe Romano
autogenerated on Wed Apr 1 2020 03:58:23