Go to the documentation of this file.00001 #include <agile_grasp/finger_hand.h>
00002
00003 FingerHand::FingerHand(double finger_width, double hand_outer_diameter,
00004 double hand_depth) :
00005 finger_width_(finger_width), hand_outer_diameter_(hand_outer_diameter), hand_depth_(
00006 hand_depth)
00007 {
00008 int n = 10;
00009
00010 Eigen::VectorXd fs_half;
00011 fs_half.setLinSpaced(n, 0.0, hand_outer_diameter - finger_width);
00012 finger_spacing_.resize(2 * fs_half.size());
00013 finger_spacing_
00014 << (fs_half.array() - hand_outer_diameter_ + finger_width_).matrix(), fs_half;
00015 fingers_ = Eigen::Array<bool, 1, Eigen::Dynamic>::Constant(1, 2 * n, false);
00016
00017
00018 }
00019
00020 void FingerHand::evaluateFingers(double bite)
00021 {
00022 back_of_hand_ = -1.0 * (hand_depth_ - bite);
00023
00024
00025 fingers_.setConstant(false);
00026
00027
00028 std::vector<int> cropped_indices;
00029 for (int i = 0; i < points_.cols(); i++)
00030 {
00031 if (points_(1, i) < bite)
00032 {
00033 cropped_indices.push_back(i);
00034
00035
00036
00037 if (points_(1, i) < back_of_hand_)
00038 {
00039 return;
00040 }
00041 }
00042 }
00043
00044 Eigen::MatrixXd cropped_points(points_.rows(), cropped_indices.size());
00045 for (int i = 0; i < cropped_indices.size(); i++)
00046 {
00047 cropped_points.col(i) = points_.col(cropped_indices[i]);
00048 }
00049
00050
00051
00052 int m = finger_spacing_.size();
00053
00054 for (int i = 0; i < m; i++)
00055 {
00056
00057
00058
00059 int num_in_gap = 0;
00060 for (int j = 0; j < cropped_indices.size(); j++)
00061 {
00062 if (cropped_points(0, j) > finger_spacing_(i)
00063 && cropped_points(0, j) < finger_spacing_(i) + finger_width_)
00064 num_in_gap++;
00065 }
00066
00067
00068 if (num_in_gap == 0)
00069 {
00070 int sum;
00071
00072 if (i <= m / 2)
00073 {
00074
00075
00076 sum = (cropped_points.row(0).array()
00077 > finger_spacing_(i) + finger_width_).count();
00078 }
00079 else
00080 {
00081
00082 sum = (cropped_points.row(0).array() < finger_spacing_(i)).count();
00083 }
00084
00085
00086
00087 if (sum > 0)
00088 {
00089
00090 fingers_(i) = true;
00091
00092 }
00093 }
00094
00095 }
00096
00097
00098 }
00099
00100 void FingerHand::evaluateHand()
00101 {
00102
00103 int n = fingers_.size() / 2;
00104
00105
00106 hand_.resize(1, n);
00107 for (int i = 0; i < n; i++)
00108 {
00109 if (fingers_(i) == 1 && fingers_(n + i) == 1)
00110 hand_(i) = 1;
00111 else
00112 hand_(i) = 0;
00113 }
00114
00115 }
00116
00117 void FingerHand::evaluateGraspParameters(double bite)
00118 {
00119
00120
00121
00122
00123
00124
00125
00126
00127 double fs_sum = 0.0;
00128 for (int i = 0; i < hand_.size(); i++)
00129 {
00130 fs_sum += finger_spacing_(i) * hand_(i);
00131 }
00132 double hor_pos = (hand_outer_diameter_ / 2.0) + (fs_sum / hand_.sum());
00133
00134
00135 grasp_bottom << hor_pos, points_.row(1).maxCoeff();
00136 grasp_surface << hor_pos, points_.row(1).minCoeff();
00137
00138
00139
00140
00141
00142
00143 std::vector<int> hand_idx;
00144 for (int i = 0; i < hand_.cols(); i++)
00145 {
00146 if (hand_(i) == true)
00147 hand_idx.push_back(i);
00148 }
00149
00150 int hand_eroded_idx = hand_idx[hand_idx.size() / 2];
00151
00152 double left_finger_pos = finger_spacing_(hand_eroded_idx);
00153 double right_finger_pos = finger_spacing_(hand_.cols() + hand_eroded_idx);
00154 double max = -100000.0;
00155 double min = 100000.0;
00156
00157 for (int i = 0; i < points_.cols(); i++)
00158 {
00159 if (points_(1, i) < bite && points_(0, i) > left_finger_pos
00160 && points_(0, i) < right_finger_pos)
00161 {
00162 if (points_(0, i) < min)
00163 min = points_(0, i);
00164 if (points_(0, i) > max)
00165 max = points_(0, i);
00166 }
00167 }
00168
00169
00170 grasp_width_ = max - min;
00171 }
00172
00173 void FingerHand::deepenHand(double init_deepness, double max_deepness)
00174 {
00175
00176
00177
00178 std::vector<int> hand_idx;
00179
00180 for (int i = 0; i < hand_.cols(); i++)
00181 {
00182 if (hand_(i) == true)
00183 hand_idx.push_back(i);
00184 }
00185
00186 if (hand_idx.size() == 0)
00187 return;
00188
00189
00190 int hand_eroded_idx = hand_idx[ceil(hand_idx.size() / 2.0) - 1];
00191 Eigen::Array<bool, 1, Eigen::Dynamic> hand_eroded = Eigen::Array<bool, 1,
00192 Eigen::Dynamic>::Constant(hand_.cols(), false);
00193 hand_eroded(hand_eroded_idx) = true;
00194
00195
00196
00197
00198
00199 double deepen_step_size = 0.005;
00200 FingerHand new_hand = *this;
00201 FingerHand last_new_hand = new_hand;
00202
00203
00204 for (double d = init_deepness + deepen_step_size; d <= max_deepness; d += deepen_step_size)
00205 {
00206
00207 new_hand.evaluateFingers(d);
00208 new_hand.evaluateHand();
00209
00210
00211
00212
00213
00214
00215 bool is_too_deep = true;
00216 for (int i = 0; i < hand_eroded.cols(); i++)
00217 {
00218 if (new_hand.hand_(i) == 1 && hand_eroded(i) == 1)
00219 {
00220 is_too_deep = false;
00221 break;
00222 }
00223 }
00224 if (is_too_deep)
00225 break;
00226 last_new_hand = new_hand;
00227
00228 }
00229 *this = last_new_hand;
00230 hand_ = hand_eroded;
00231
00232
00233 }