00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <pr2_gripper_sensor_controller/pressure_observer.h>
00042
00043
00044 void pressureObserver::spin()
00045 {
00046
00047
00048 if(updatePressureState())
00049 {
00050
00051 time_prev = time_cur;
00052 time_cur = ros::Time::now().toSec();
00053
00054 zero();
00055 bias_estimator();
00056 updateTotalLoading();
00057 updateXYCentroids();
00058 updateBrokenSensorStatus();
00059
00060 updateContactState();
00061 }
00062
00063 }
00064
00065
00066 void pressureObserver::updateBrokenSensorStatus()
00067 {
00068 if(getPadForce(pressure_now.pressure_left) == 0 || getPadForce(pressure_now.pressure_left) == 0)
00069 broken_sensor = true;
00070 else
00071 broken_sensor = false;
00072
00073 }
00074
00075
00076
00077
00078 void pressureObserver::bias_estimator()
00079 {
00080
00081 double poshp_fc = 5.0;
00082 double poshp_lambda = 2*3.14159265*poshp_fc;
00083 double dt = .041;
00084
00085
00086 for( int i = 0; (i < 22); i ++)
00087 {
00088 pressure_prev_bias.pressure_left[i] = pressure_cur_bias.pressure_left[i];
00089 pressure_prev_bias.pressure_right[i] = pressure_cur_bias.pressure_right[i];
00090
00091 pressure_cur_bias.pressure_left[i] = ((1/(1+dt*poshp_lambda))*pressure_prev_bias.pressure_left[i]) + ((1/(1+dt*poshp_lambda))*(pressure_current_zerod.pressure_left[i]-pressure_prev_zerod.pressure_left[i]));
00092 pressure_cur_bias.pressure_right[i] = ((1/(1+dt*poshp_lambda))*pressure_prev_bias.pressure_right[i]) + ((1/(1+dt*poshp_lambda))*(pressure_current_zerod.pressure_right[i]-pressure_prev_zerod.pressure_right[i]));
00093
00094
00095 pressure_bp.pressure_left[i] = pressureLFFilt_left[i]->getNextFilteredValue(pressure_current_zerod.pressure_left[i]);
00096 pressure_bp.pressure_right[i] = pressureLFFilt_right[i]->getNextFilteredValue(pressure_current_zerod.pressure_right[i]);
00097
00098 pressure_cur_bias.rostime = ros::Time::now().toSec();
00099 }
00100 }
00101
00102
00103 bool pressureObserver::checkPlaceContact(double dF)
00104 {
00105 if( checkSlip(dF,0.2) || placeContact )
00106 placeContact = true;
00107 else
00108 placeContact = false;
00109 return placeContact;
00110 }
00111
00112
00113 int pressureObserver::checkSideImpact(double dF)
00114 {
00115 for(int i = 0; i < 7; i++)
00116 {
00117
00118 if( (pressure_cur_bias.pressure_left[i]/500.0) > dF )
00119 return i+1;
00120 if( (pressure_cur_bias.pressure_right[i]/500.0) > dF )
00121 return i+10;
00122 }
00123 return -1;
00124 }
00125
00126
00127
00128
00129 bool pressureObserver::graspContact(int contactsDesired)
00130 {
00131
00132
00133 if( contactsDesired == 0 && left_contact && right_contact)
00134 return true;
00135
00136 else if( (contactsDesired == 1 && left_contact) || (contactsDesired == 2 && right_contact))
00137 return true;
00138
00139 else if( (contactsDesired ==3) && (left_contact || right_contact) )
00140 return true;
00141
00142 return false;
00143 }
00144
00145
00146
00147 void pressureObserver::updateContactState()
00148 {
00149
00150
00151 if(fabs(padForce_left_cur) > hpForceTrigger || padForce_left_cur_nonbiased > forceLightest-.25 )
00152 left_contact = true;
00153 else
00154 left_contact = false;
00155
00156 if(fabs(padForce_right_cur) > hpForceTrigger || padForce_right_cur_nonbiased > forceLightest-.25 )
00157 right_contact = true;
00158 else
00159 right_contact = false;
00160 }
00161
00162
00163
00164 void pressureObserver::updateTotalLoading()
00165 {
00166
00167 padForce_left_prev = padForce_left_cur;
00168 padForce_right_prev = padForce_right_cur;
00169
00170
00171 padForce_left_cur = getPadForce(pressure_cur_bias.pressure_left);
00172 padForce_right_cur = getPadForce(pressure_cur_bias.pressure_right);
00173 padForce_left_cur_nonbiased = getPadForce(pressure_current_zerod.pressure_left);
00174 padForce_right_cur_nonbiased = getPadForce(pressure_current_zerod.pressure_right);
00175 padForce_cur = (padForce_left_cur + padForce_right_cur)/2.0;
00176 padForce_cur_nonbiased = (padForce_left_cur_nonbiased + padForce_right_cur_nonbiased)/2.0;
00177
00178
00179 totalLoading_left = fabs((padForce_left_cur-padForce_left_prev)/(dt));
00180 totalLoading_right = fabs((padForce_right_cur-padForce_right_prev)/(dt));
00181 totalLoading_prev = totalLoading;
00182 totalLoading = (totalLoading_left+totalLoading_right)/2.0;
00183
00184 lfForce_left = getPadForce(pressure_bp.pressure_left);
00185 lfForce_right = getPadForce(pressure_bp.pressure_right);
00186 }
00187
00188
00189
00190 double pressureObserver::getPadForce(boost::array<double,22> pressureArray)
00191 {
00192 double tempLoading = 0.0;
00193
00194
00195 for( int i = 7; i < 22; i ++)
00196 {
00197 tempLoading += pressureArray[i];
00198 }
00199
00200 return tempLoading/UNITS_PER_N;
00201
00202 }
00203
00204
00205
00206 void pressureObserver::updateZeros2()
00207 {
00208 double
00209 zero_weight = 0.6;
00210 for( int i = 0; i < 22; i ++)
00211 {
00212 zero_offset.pressure_left[i] = ( ((1.0-zero_weight)*zero_offset.pressure_left[i]) + (zero_weight*pressure_current.pressure_left[i]) );
00213 zero_offset.pressure_right[i] = ( ((1.0-zero_weight)*zero_offset.pressure_right[i]) + (zero_weight*pressure_current.pressure_right[i]) );
00214 }
00215 }
00216
00217
00218
00219 void pressureObserver::zero()
00220 {
00221
00222 for( int i = 0; i < 22; i ++)
00223 {
00224 pressure_prev_zerod.pressure_left[i] = pressure_current_zerod.pressure_left[i];
00225 pressure_prev_zerod.pressure_right[i] = pressure_current_zerod.pressure_right[i];
00226
00227 pressure_current_zerod.pressure_left[i] = pressure_current.pressure_left[i] - zero_offset.pressure_left[i];
00228 pressure_current_zerod.pressure_right[i] = pressure_current.pressure_right[i] - zero_offset.pressure_right[i];
00229 }
00230 }
00231
00232
00233
00234
00235 bool pressureObserver::updatePressureState()
00236 {
00237
00238 bool newData = false;
00239 bool updated = false;
00240
00241
00242 std::vector< uint16_t > pressureVector_left = left_finger->state_.data_;
00243 std::vector< uint16_t > pressureVector_right = right_finger->state_.data_;
00244 for( int i = 0; i < 22; i ++)
00245 {
00246 pressure_now.pressure_left[i] = (double)pressureVector_left[i];
00247 pressure_now.pressure_right[i] = (double)pressureVector_right[i];
00248
00249
00250 if(pressure_now.pressure_left[i] != pressure_current.pressure_left[i] || pressure_now.pressure_right[i] != pressure_current.pressure_right[i])
00251 {
00252 newData = true;
00253 }
00254 }
00255
00256
00257
00258 if( newData || subSample_cnt >= subSample_steps)
00259 {
00260
00261 for( int i = 0; i < 22; i ++)
00262 {
00263
00264 pressure_prev.pressure_left[i] = pressure_current.pressure_left[i];
00265 pressure_prev.pressure_right[i] = pressure_current.pressure_right[i];
00266
00267
00268 pressure_current.pressure_left[i] = pressure_now.pressure_left[i];
00269 pressure_current.pressure_right[i] = pressure_now.pressure_right[i];
00270 }
00271
00272 subSample_cnt = 0;
00273
00274 updated = true;
00275 }
00276
00277
00278 subSample_cnt++;
00279
00280 return updated;
00281 }
00282
00283
00284 void pressureObserver::getPadCentroid(boost::array<double,22> pressureArray, double *x, double *y)
00285 {
00286
00287 double y_weights[15] = {-1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1};
00288 double x_weights[15] = {-1, -1, -1, -0.5, -0.5, -0.5, 0, 0, 0, 0.5, 0.5, 0.5, 1, 1, 1};
00289
00290 *y = 0;
00291 *x = 0;
00292
00293 for(int i = 7; i < 22; i++)
00294 {
00295 *y += pressureArray[i]*y_weights[i-7];
00296 *x += pressureArray[i]*x_weights[i-7];
00297 }
00298
00299
00300 double pressureSum = getPadForce(pressureArray);
00301 *y = *y/pressureSum;
00302 *x = *x/pressureSum;
00303 }
00304
00305 void pressureObserver::updateXYCentroids()
00306 {
00307 double x_centroid_left, y_centroid_left, x_centroid_right, y_centroid_right;
00308 getPadCentroid(pressure_current_zerod.pressure_left,&x_centroid_left,&y_centroid_left);
00309 getPadCentroid(pressure_current_zerod.pressure_right,&x_centroid_right,&y_centroid_right);
00310
00311 }
00312
00313
00314 bool pressureObserver::checkSlip(double slip_motion_limit, double slip_force_limit)
00315 {
00316 double disturbance_left = std::min(std::max(slip_motion_limit*fabs(padForce_left_cur_nonbiased), .048),0.2);
00317 double disturbance_right = std::min(std::max(slip_motion_limit*fabs(padForce_right_cur_nonbiased), .048),0.2);
00318
00319 if( ( fabs(padForce_left_cur) > disturbance_left) && (fabs(lfForce_left) < slip_force_limit))
00320 return true;
00321 else if( ( fabs(padForce_right_cur) > disturbance_right) && (fabs(lfForce_right) < slip_force_limit))
00322 return true;
00323 else
00324 return false;
00325 }
00326
00327
00328
00329 pressureObserver::pressureObserver(pr2_hardware_interface::PressureSensor* left,pr2_hardware_interface::PressureSensor* right)
00330 {
00331
00332 left_finger = left;
00333 right_finger = right;
00334
00335
00336 subSample_cnt = 1;
00337
00338
00339 subSample_steps = 41;
00340
00341
00342 padForce_left_cur = 0.0;
00343 padForce_right_cur = 0.0;
00344 padForce_left_prev = 0.0;
00345 padForce_right_prev = 0.0;
00346
00347
00348 time_prev = ros::Time::now().toSec();
00349 time_cur = ros::Time::now().toSec();
00350 dt = 0.041;
00351
00352
00353 left_contact = false;
00354 right_contact = false;
00355
00356
00357 placeContact = false;
00358
00359
00360 updatePressureState();
00361
00362
00363 for( int i = 0; i < 22; i ++)
00364 {
00365 zero_offset.pressure_left[i] = pressure_now.pressure_left[i];
00366 zero_offset.pressure_right[i] = pressure_now.pressure_right[i];
00367 }
00368
00369
00370
00371
00372 float b_vfilt[] = { 0.6323, 0, -0.6323};
00373 float a_vfilt[] = {1.0, -0.6294, -0.2647};
00374 for(int i=0; i < 22; i++)
00375 {
00376 pressureLFFilt_left[i] = new digitalFilter(1+1, true,b_vfilt,a_vfilt);
00377 pressureLFFilt_right[i] = new digitalFilter(1+1, true,b_vfilt,a_vfilt);
00378 }
00379 }
00380
00381
00382
00383 pressureObserver::~pressureObserver()
00384 {
00385 delete[] pressureLFFilt_left;
00386 delete[] pressureLFFilt_right;
00387 }