00001
00002
00003 #include <sbpl_arm_planner/pr2/pr2_workspace.h>
00004
00005 double lower_corner_x = -0.6;
00006 double lower_corner_y = -1.25;
00007 double lower_corner_z = -0.05;
00008 double grid_size_x = 1.6;
00009 double grid_size_y = 1.6;
00010 double grid_size_z = 1.4;
00011
00012 double resolution_x = 0.02;
00013 double resolution_y = 0.02;
00014 double resolution_z = 0.02;
00015 double pan_res = 0.06981;
00016
00017 double shoulder_pan_x = -0.050;
00018 double shoulder_pan_y = -0.188;
00019 double shoulder_pan_z = 0.743;
00020
00021 double L_up_arm = 0.410;
00022 double L_fo_arm = 0.321;
00023 double L_sh = 0.100;
00024
00025 double jnt_min[] = {-2.285, -0.523, -3.899, -2.299};
00026 double jnt_max[] = { 0.714, 1.396, 0.850, 0.000};
00027
00028 double fo_arm_up_arm_angle_offset = 0.0;
00029 #define OFFSET fo_arm_up_arm_angle_offset
00030 #define PI 3.14159
00031
00032
00033 void grid2world(long i, long j, long k, double& x, double& y, double& z) {
00034 x = lower_corner_x + (double(i)+0.5)*resolution_x;
00035 y = lower_corner_y + (double(j)+0.5)*resolution_y;
00036 z = lower_corner_z + (double(k)+0.5)*resolution_z;
00037 }
00038
00039
00040 void world2grid(double x, double y, double z, long& i, long& j, long& k) {
00041 double temp;
00042 double a, b, c;
00043 temp = modf(x/resolution_x, &a);
00044 temp = modf(y/resolution_y, &b);
00045 temp = modf(z/resolution_z, &c);
00046 i = long(a);
00047 j = long(b);
00048 k = long(c);
00049 }
00050
00051
00052
00053
00054
00055 vector<vector<double> > elbow_positions_given_pan(double x1, double y1, double z1, double r1, double x2, double y2, double z2, double r2, double vect[3]) {
00056
00057
00058
00059
00060 vector<vector<double> > list_of_points;
00061 double sphere1_cent[] = {x1, y1, z1};
00062 double sphere2_cent[] = {x2, y2, z2};
00063 double cent12cent2_dist = distance_between(sphere1_cent, sphere2_cent, 3);
00064
00065
00066
00067
00068 if ( cent12cent2_dist >= (r1+r2) ) {
00069 return list_of_points;
00070 }
00071
00072
00073 double cent12cent2_vect[] = {x2-x1, y2-y1, z2-z1};
00074
00075
00076
00077
00078 double dot_prod = (pow(r1,2) + pow(cent12cent2_dist, 2) - pow(r2, 2))/2;
00079 double A = r1*vect[0]*cent12cent2_vect[0] + r1*vect[1]*cent12cent2_vect[1];
00080 double B = r1*cent12cent2_vect[2];
00081
00082 double alpha1 = asin((2*B*dot_prod + sqrt(pow(2*B*dot_prod, 2) - 4*(pow(A,2) + pow(B,2))*(pow(dot_prod,2) - pow(A,2))))/(2*(pow(A,2) + pow(B,2))));
00083 double alpha2 = asin((2*B*dot_prod - sqrt(pow(2*B*dot_prod, 2) - 4*(pow(A,2) + pow(B,2))*(pow(dot_prod,2) - pow(A,2))))/(2*(pow(A,2) + pow(B,2))));
00084
00085
00086 if (alpha1 != alpha1 || alpha2 != alpha2) return list_of_points;
00087
00088 vector<double> solution1;
00089 vector<double> solution2;
00090
00091 solution1.push_back(x1 + r1*cos(alpha1)*vect[0]);
00092 solution1.push_back(y1 + r1*cos(alpha1)*vect[1]);
00093 solution1.push_back(z1 + r1*sin(alpha1));
00094
00095 solution2.push_back(x1 + r1*cos(alpha2)*vect[0]);
00096 solution2.push_back(y1 + r1*cos(alpha2)*vect[1]);
00097 solution2.push_back(z1 + r1*sin(alpha2));
00098
00099
00100
00101
00102 double tolerance = 1/pow(10,2);
00103 if ((fabs(distance_between(solution1, sphere2_cent, 3) - r2)) > tolerance || fabs(distance_between(solution2, sphere2_cent, 3) - r2) > tolerance)
00104 return list_of_points;
00105
00106 list_of_points.push_back(solution1);
00107 list_of_points.push_back(solution2);
00108 return list_of_points;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 bool check_joint_limits_and_append_joint_angles(double pan, double shlift_wrt_shpan_uvect[3], double shlift[3], vector<double>& elbow_pose, double endeff_pose[3]) {
00118
00119
00120 elbow_pose.push_back(pan);
00121
00122
00123 double up_arm_uvect[] = {elbow_pose[0] - shlift[0], elbow_pose[1] - shlift[1], elbow_pose[2] - shlift[2]};
00124 double nm = vect_norm(up_arm_uvect, 3);
00125 up_arm_uvect[0] /= nm;
00126 up_arm_uvect[1] /= nm;
00127 up_arm_uvect[2] /= nm;
00128
00129 double dot_prod = dot_product(shlift_wrt_shpan_uvect, up_arm_uvect, 3);
00130 if ((elbow_pose[2] > shlift[2] && dot_prod < cos(jnt_min[1])) || (elbow_pose[2] <= shlift[2] && dot_prod < cos(jnt_max[1]))) {
00131 return 0;
00132 }
00133
00134
00135 double lift = (elbow_pose[2] >= shlift[2] ) ? -acos(dot_prod) : acos(dot_prod);
00136 elbow_pose.push_back(lift);
00137
00138
00139 double fo_arm_uvect[] = {endeff_pose[0] - elbow_pose[0], endeff_pose[1] - elbow_pose[1], endeff_pose[2] - elbow_pose[2]};
00140 nm = vect_norm(fo_arm_uvect, 3);
00141 fo_arm_uvect[0] /= nm;
00142 fo_arm_uvect[1] /= nm;
00143 fo_arm_uvect[2] /= nm;
00144
00145 dot_prod = dot_product(up_arm_uvect, fo_arm_uvect, 3);
00146 if((dot_prod > 0 && dot_prod > cos(OFFSET)) || (dot_prod < 0 && dot_prod < cos(-jnt_min[3]+OFFSET))) {
00147 return 0;
00148 }
00149
00150
00151 double flex = acos(dot_prod);
00152 elbow_pose.push_back(flex);
00153
00154
00155 double up_arm_proj[] = {up_arm_uvect[0], up_arm_uvect[1], 0};
00156 double up_arm_proj_norm = vect_norm(up_arm_proj, 3);
00157
00158 up_arm_proj[0] /= up_arm_proj_norm;
00159 up_arm_proj[1] /= up_arm_proj_norm;
00160
00161 double up_arm_proj_perp[] = {-up_arm_proj[1], up_arm_proj[0], 0};
00162 double ref_uvect[3];
00163 cross_product(ref_uvect, up_arm_uvect, up_arm_proj_perp);
00164 double fo_arm_proj_uvect[] = {fo_arm_uvect[0] - dot_prod*up_arm_uvect[0], fo_arm_uvect[1] - dot_prod*up_arm_uvect[1], fo_arm_uvect[2] - dot_prod*up_arm_uvect[2]};
00165 double fo_arm_proj_norm = vect_norm(fo_arm_proj_uvect, 3);
00166
00167 fo_arm_proj_uvect[0] /= fo_arm_proj_norm;
00168 fo_arm_proj_uvect[1] /= fo_arm_proj_norm;
00169 fo_arm_proj_uvect[2] /= fo_arm_proj_norm;
00170
00171 double ref_min_uvect[3], ref_max_uvect[3];
00172 rotate_vector(ref_min_uvect, ref_uvect, up_arm_uvect, jnt_min[2]);
00173 rotate_vector(ref_max_uvect, ref_uvect, up_arm_uvect, jnt_max[2]);
00174 double tolerance = 1/pow(10, 2);
00175 double direction[3] ;
00176 cross_product(direction, ref_min_uvect, ref_max_uvect);
00177 bool roll_acceptable = 0;
00178 if (fabs(acos(dot_product(ref_min_uvect, ref_max_uvect, 3)) - acos(dot_product(ref_min_uvect, fo_arm_proj_uvect, 3)) - acos(dot_product(ref_max_uvect, fo_arm_proj_uvect, 3))) < tolerance) {
00179 if (vect_divide(direction, up_arm_uvect, 3) > 0){
00180 roll_acceptable = 1;
00181 }
00182 }
00183 else {
00184 if (vect_divide(direction, up_arm_uvect, 3) < 0) {
00185 roll_acceptable = 1;
00186 }
00187 }
00188
00189
00190 if (!roll_acceptable) {
00191 return 0;
00192 }
00193 else {
00194 dot_prod = dot_product(ref_uvect, fo_arm_proj_uvect, 3);
00195 double roll;
00196 cross_product(direction, ref_uvect, fo_arm_proj_uvect);
00197 if (vect_divide(direction, up_arm_uvect, 3) >= 0 && dot_prod > 0) {
00198 roll = acos(dot_prod);
00199 }
00200 else {
00201 if (vect_divide(direction, up_arm_uvect, 3) < 0) {
00202 roll = -acos(dot_prod);
00203 }
00204 else {
00205 roll = -(2*PI - acos(dot_prod));
00206 }
00207 }
00208 elbow_pose.push_back(roll);
00209 return 1;
00210 }
00211 }
00212
00213 bool check_joint_limits(double shlift_wrt_shpan_uvect[3], double shlift[3], vector<double> elbow_pose, double endeff_pose[3]) {
00214
00215 double up_arm_uvect[] = {elbow_pose[0] - shlift[0], elbow_pose[1] - shlift[1], elbow_pose[2] - shlift[2]};
00216
00217 up_arm_uvect[0] /= L_up_arm;
00218 up_arm_uvect[1] /= L_up_arm;
00219 up_arm_uvect[2] /= L_up_arm;
00220
00221 double dp = dot_product(shlift_wrt_shpan_uvect, up_arm_uvect, 3);
00222 if ((elbow_pose[2] > shlift[2] && dp < cos(jnt_min[1])) || (elbow_pose[2] <= shlift[2] && dp < cos(jnt_max[1]))) {
00223 return 0;
00224 }
00225
00226
00227 double fo_arm_uvect[] = {endeff_pose[0] - elbow_pose[0], endeff_pose[1] - elbow_pose[1], endeff_pose[2] - elbow_pose[2]};
00228
00229 fo_arm_uvect[0] /= L_fo_arm;
00230 fo_arm_uvect[1] /= L_fo_arm;
00231 fo_arm_uvect[2] /= L_fo_arm;
00232
00233 double dot_prod = dot_product(up_arm_uvect, fo_arm_uvect, 3);
00234 if((dot_prod > 0 && dot_prod > cos(OFFSET)) || (dot_prod < 0 && dot_prod < cos(-jnt_min[3]+OFFSET))) {
00235 return 0;
00236 }
00237
00238
00239 double up_arm_proj[] = {up_arm_uvect[0], up_arm_uvect[1], 0};
00240 double up_arm_proj_norm = vect_norm(up_arm_proj, 3);
00241
00242 up_arm_proj[0] /= up_arm_proj_norm;
00243 up_arm_proj[1] /= up_arm_proj_norm;
00244
00245 double up_arm_proj_perp[] = {-up_arm_proj[1], up_arm_proj[0], 0};
00246 double ref_uvect[3];
00247 cross_product(ref_uvect, up_arm_uvect, up_arm_proj_perp);
00248
00249 double fo_arm_proj_uvect[] = {fo_arm_uvect[0] - L_fo_arm*dot_prod*up_arm_uvect[0], fo_arm_uvect[1] - L_fo_arm*dot_prod*up_arm_uvect[1], fo_arm_uvect[2] - L_fo_arm*dot_prod*up_arm_uvect[2]};
00250 double fo_arm_proj_norm = vect_norm(fo_arm_proj_uvect, 3);
00251
00252 fo_arm_proj_uvect[0] /= fo_arm_proj_norm;
00253 fo_arm_proj_uvect[1] /= fo_arm_proj_norm;
00254 fo_arm_proj_uvect[2] /= fo_arm_proj_norm;
00255
00256 double ref_min_uvect[3], ref_max_uvect[3];
00257 rotate_vector(ref_min_uvect, ref_uvect, up_arm_uvect, jnt_min[2]);
00258 rotate_vector(ref_max_uvect, ref_uvect, up_arm_uvect, jnt_max[2]);
00259
00260 double tolerance = 1/pow(10, 2);
00261 double direction[3];
00262 cross_product(direction, ref_min_uvect, ref_max_uvect);
00263 if (fabs(acos(dot_product(ref_min_uvect, ref_max_uvect, 3)) - acos(dot_product(ref_min_uvect, fo_arm_proj_uvect, 3)) - acos(dot_product(ref_max_uvect, fo_arm_proj_uvect, 3))) < tolerance) {
00264 if (vect_divide(direction, up_arm_uvect, 3) < 0){
00265 return 0;
00266 }
00267 else
00268 return 1;
00269 }
00270 else {
00271 if (vect_divide(direction, up_arm_uvect, 3) > 0) {
00272 return 0;
00273 }
00274 else
00275 return 1;
00276 }
00277 }
00278
00279
00280
00281
00282
00283 vector<vector<double> > elbow_positions_given_endeff_pose(double pan_start, double resolution, double x, double y, double z) {
00284 vector<vector<double> > list_of_accepted_points;
00285
00286 double endeff_pose[] = {x, y, z};
00287 vector<vector<double> > elbow_positions_possible;
00288
00289 double shlift_wrt_shpan_uvect[3]; shlift_wrt_shpan_uvect[2] = 0;
00290 double shlift_cent[3];
00291
00292
00293
00294
00295 pan_res = resolution;
00296
00297 for (double pan = pan_start; pan <= jnt_max[0]; pan += pan_res) {
00298 shlift_wrt_shpan_uvect[0] = cos(pan);
00299 shlift_wrt_shpan_uvect[1] = sin(pan);
00300
00301 shlift_cent[0] = shoulder_pan_x + L_sh*shlift_wrt_shpan_uvect[0];
00302 shlift_cent[1] = shoulder_pan_y + L_sh*shlift_wrt_shpan_uvect[1];
00303 shlift_cent[2] = shoulder_pan_z;
00304 elbow_positions_possible = elbow_positions_given_pan(shlift_cent[0], shlift_cent[1], shlift_cent[2], L_up_arm, x, y, z, L_fo_arm, shlift_wrt_shpan_uvect);
00305
00306
00307 if (!elbow_positions_possible.empty()) {
00308 for (unsigned int i = 0; i < elbow_positions_possible.size(); i++) {
00309 if (check_joint_limits_and_append_joint_angles(pan, shlift_wrt_shpan_uvect, shlift_cent, elbow_positions_possible[i], endeff_pose)) {
00310 list_of_accepted_points.push_back(elbow_positions_possible[i]);
00311 }
00312 }
00313 }
00314 }
00315 for (double pan = pan_start-pan_res; pan >= jnt_min[0]; pan -= pan_res) {
00316 shlift_wrt_shpan_uvect[0] = cos(pan);
00317 shlift_wrt_shpan_uvect[1] = sin(pan);
00318
00319 shlift_cent[0] = shoulder_pan_x + L_sh*shlift_wrt_shpan_uvect[0];
00320 shlift_cent[1] = shoulder_pan_y + L_sh*shlift_wrt_shpan_uvect[1];
00321 shlift_cent[2] = shoulder_pan_z;
00322 elbow_positions_possible = elbow_positions_given_pan(shlift_cent[0], shlift_cent[1], shlift_cent[2], L_up_arm, x, y, z, L_fo_arm, shlift_wrt_shpan_uvect);
00323
00324
00325 if (!elbow_positions_possible.empty()) {
00326 for (unsigned int i = 0; i < elbow_positions_possible.size(); i++) {
00327 if (check_joint_limits_and_append_joint_angles(pan, shlift_wrt_shpan_uvect, shlift_cent, elbow_positions_possible[i], endeff_pose)) {
00328 list_of_accepted_points.push_back(elbow_positions_possible[i]);
00329 }
00330 }
00331 }
00332 }
00333 return list_of_accepted_points;
00334 }
00335
00336 void elbow_positions_given_endeff_pose(vector<vector<double> >& list_of_accepted_points, vector<vector<double> >& list_of_rejected_points, double pan_start, double resolution, double x, double y, double z) {
00337 double endeff_pose[] = {x, y, z};
00338 vector<vector<double> > elbow_positions_possible;
00339
00340 double shlift_wrt_shpan_uvect[3]; shlift_wrt_shpan_uvect[2] = 0;
00341 double shlift_cent[3];
00342
00343
00344
00345
00346 pan_res = resolution;
00347 for (double pan = pan_start; pan <= jnt_max[0]; pan += pan_res) {
00348 shlift_wrt_shpan_uvect[0] = cos(pan);
00349 shlift_wrt_shpan_uvect[1] = sin(pan);
00350
00351 shlift_cent[0] = shoulder_pan_x + L_sh*shlift_wrt_shpan_uvect[0];
00352 shlift_cent[1] = shoulder_pan_y + L_sh*shlift_wrt_shpan_uvect[1];
00353 shlift_cent[2] = shoulder_pan_z;
00354 elbow_positions_possible = elbow_positions_given_pan(shlift_cent[0], shlift_cent[1], shlift_cent[2], L_up_arm, x, y, z, L_fo_arm, shlift_wrt_shpan_uvect);
00355
00356
00357 if (!elbow_positions_possible.empty()) {
00358 for (unsigned int i = 0; i < elbow_positions_possible.size(); i++) {
00359 if (check_joint_limits_and_append_joint_angles(pan, shlift_wrt_shpan_uvect, shlift_cent, elbow_positions_possible[i], endeff_pose)) {
00360 list_of_accepted_points.push_back(elbow_positions_possible[i]);
00361 }
00362 else {
00363 list_of_rejected_points.push_back(elbow_positions_possible[i]);
00364 }
00365 }
00366 }
00367 }
00368 for (double pan = pan_start-pan_res; pan >= jnt_min[0]; pan -= pan_res) {
00369 shlift_wrt_shpan_uvect[0] = cos(pan);
00370 shlift_wrt_shpan_uvect[1] = sin(pan);
00371
00372 shlift_cent[0] = shoulder_pan_x + L_sh*shlift_wrt_shpan_uvect[0];
00373 shlift_cent[1] = shoulder_pan_y + L_sh*shlift_wrt_shpan_uvect[1];
00374 shlift_cent[2] = shoulder_pan_z;
00375 elbow_positions_possible = elbow_positions_given_pan(shlift_cent[0], shlift_cent[1], shlift_cent[2], L_up_arm, x, y, z, L_fo_arm, shlift_wrt_shpan_uvect);
00376
00377
00378 if (!elbow_positions_possible.empty()) {
00379 for (unsigned int i = 0; i < elbow_positions_possible.size(); i++) {
00380 if (check_joint_limits_and_append_joint_angles(pan, shlift_wrt_shpan_uvect, shlift_cent, elbow_positions_possible[i], endeff_pose)) {
00381 list_of_accepted_points.push_back(elbow_positions_possible[i]);
00382 }
00383 else {
00384 list_of_rejected_points.push_back(elbow_positions_possible[i]);
00385 }
00386 }
00387 }
00388 }
00389 }
00390
00391
00392
00393
00394 void separate_rejected_points(vector<vector<double> > list_of_rejected_points, vector<vector<double> >& rejected_due_to_lift, vector<vector<double> >& rejected_due_to_flex, vector<vector<double> >& rejected_due_to_roll) {
00395 int len = list_of_rejected_points.size();
00396 vector<double> point;
00397 int size_of_point;
00398 for (int i = 0; i < len; i++) {
00399 point.clear();
00400 point = list_of_rejected_points[i];
00401 size_of_point = point.size();
00402 switch (size_of_point) {
00403 case 4: {
00404 rejected_due_to_lift.push_back(point);
00405 break;
00406 }
00407 case 5: {
00408 rejected_due_to_flex.push_back(point);
00409 break;
00410 }
00411 case 6: {
00412 rejected_due_to_roll.push_back(point);
00413 break;
00414 }
00415 default: {
00416 break;
00417 }
00418 }
00419 }
00420 }
00421
00422
00423
00424 bool position(long i, long j, long k) {
00425 double x, y, z;
00426 grid2world(i, j, k, x, y, z);
00427 double endeff_pose[] = {x, y, z};
00428
00429 vector<vector<double> > elbow_positions_possible;
00430
00431 double shlift_wrt_shpan_uvect[3]; shlift_wrt_shpan_uvect[2] = 0;
00432 double shlift_cent[3];
00433
00434 bool possible_at_least_once = 0;
00435
00436 for (double pan = jnt_min[0]; pan <=jnt_max[0]; pan += pan_res) {
00437 shlift_wrt_shpan_uvect[0] = cos(pan);
00438 shlift_wrt_shpan_uvect[1] = sin(pan);
00439
00440 shlift_cent[0] = shoulder_pan_x + L_sh*shlift_wrt_shpan_uvect[0];
00441 shlift_cent[1] = shoulder_pan_y + L_sh*shlift_wrt_shpan_uvect[1];
00442 shlift_cent[2] = shoulder_pan_z;
00443
00444 elbow_positions_possible = elbow_positions_given_pan(shlift_cent[0], shlift_cent[1], shlift_cent[2], L_up_arm, x, y, z, L_fo_arm, shlift_wrt_shpan_uvect);
00445
00446 if (!elbow_positions_possible.empty()) {
00447 for (unsigned int i = 0; i < elbow_positions_possible.size(); i++) {
00448 if (check_joint_limits(shlift_wrt_shpan_uvect, shlift_cent, elbow_positions_possible[i], endeff_pose)) {
00449 possible_at_least_once = 1;
00450 break;
00451 }
00452 }
00453 }
00454 if (possible_at_least_once) break;
00455 }
00456 return possible_at_least_once;
00457 }