00001
00002
00003
00004 #include"tensor_field_nav_core/TfCore.h"
00005
00006 TfCore::TfCore(ros::NodeHandle private_nh_ ):nh_(),m_it(nh_)
00007 {
00008
00009 major_iframe = 0;
00010 quadmesh = NULL;
00011 ntenelems = 0;
00012 nten_regelems = 0;
00013 ndegpts = 0;
00014 ten_regularelems=NULL;
00015 degpts = NULL;
00016 curMaxNumTenRegElems =100;
00017 MaxNumDegeneratePts = 200;
00018 ten_tmax = NPIX/(SCALE*NPN);
00019 ten_dmax = SCALE/NPIX;
00020 iframe = 0;
00021 Npat = 32;
00022 alpha = (0.12*255);
00023 tmax = NPIX/(SCALE*NPN);
00024 dmax = SCALE/NPIX;
00025 ten_designelems = NULL;
00026 curMaxNumTenDesignElems = 100;
00027 ndegenerate_tris = 0;
00028 degenerate_tris = NULL;
00029 major_path=NULL;
00030 NUM_Slices = 0;
00031 keyframes = NULL;
00032 enRelaxKeyframeOn=false;
00033 InterpScheme=1;
00034 curSliceID=0;
00035 showGridOn=false;
00036 showIBFVOn=true;
00037 showRegularElemOn=false;
00038 showSingularitiesOn=false;
00039 showMajorTenLine=true;
00040 interFrameNum=3;
00041 interFrameTime=0.2;
00042
00043 isReceiveNewMap=false;
00044 ifReachTrisector=false;
00045 targetTrisectorIndex=-1;
00046 safeDistance=0.3;
00047 realWorld_to_field_scale=25;
00048 realWorld_to_field_offset_x=0.5;
00049 realWorld_to_field_offset_y=0.5;
00050 rgb_im = (unsigned char *)malloc(NPIX * NPIX*3* sizeof(unsigned char));
00051
00052
00053 robotInitialPos_x=0.5;
00054 robotInitialPos_y=0.5;
00055 rgbTopicName="/tf_image";
00056 gridMapTopicName="/projected_map";
00057 worldFrameId="odom";
00058 baseFrameId="base_footprint";
00059 ifCancelPath=false;
00060 ifFinish_goTri=false;
00061 reGenPath=false;
00062
00063
00064 ros::NodeHandle private_nh(private_nh_);
00065 private_nh.param("world_to_field_scale", realWorld_to_field_scale, realWorld_to_field_scale);
00066 private_nh.param("world_to_field_offset_x", realWorld_to_field_offset_x, realWorld_to_field_offset_x);
00067 private_nh.param("world_to_field_offset_y", realWorld_to_field_offset_y, realWorld_to_field_offset_y);
00068 private_nh.param("robot_initial_pos_x", robotInitialPos_x, robotInitialPos_x);
00069 private_nh.param("robot_initial_pos_y", robotInitialPos_y, robotInitialPos_y);
00070 private_nh.param("rgb_pub_topic_name", rgbTopicName, rgbTopicName);
00071 private_nh.param("gridMap_topic_name", gridMapTopicName, gridMapTopicName);
00072 private_nh.param("world_frame_id", worldFrameId, worldFrameId);
00073 private_nh.param("base_frame_id", baseFrameId, baseFrameId);
00074 private_nh.param("safe_disance", safeDistance, safeDistance);
00075 private_nh.param("inter_frame_num", interFrameNum, interFrameNum);
00076 private_nh.param("inter_frame_time", interFrameTime, interFrameTime);
00077
00078 rgb_pub = m_it.advertise(rgbTopicName, 1);
00079 gridmap_sub=nh_.subscribe(gridMapTopicName,1,&TfCore::gridMap_callback,this);
00080 frontierPoints_sub=nh_.subscribe("frontier_points",1,&TfCore::frontier_point_callback,this);
00081 goTriExecuteclient=nh_.serviceClient<pure_pursuit_controller::executePath>("execute_goTri");
00082 pathExecuteClient=nh_.serviceClient<pure_pursuit_controller::executePath>("execute_path");
00083 pathCancelClient=nh_.serviceClient<pure_pursuit_controller::cancelPath>("cancel_path");
00084 pathCutClient=nh_.serviceClient<pure_pursuit_controller::cutPath>("cut_path");
00085 finishGoTri=nh_.subscribe("/pure_pursuit_controller/finish_go_tri",1,&TfCore::goTri_callback,this);
00086
00087 robot_loc=new Seed();
00088 robot_loc->pos[0]=robotInitialPos_x;
00089 robot_loc->pos[1]=robotInitialPos_y;
00090 robot_loc->triangle=0;
00091 realWorld_to_field_scale=realWorld_to_field_scale;
00092 realWorld_to_field_offset_x=realWorld_to_field_offset_x;
00093 realWorld_to_field_offset_y=realWorld_to_field_offset_y;
00094
00095 }
00096
00097 TfCore::~TfCore(){
00098 for(int i=0;i<m_myThreads.size();i++)
00099 delete m_myThreads[i];
00100 delete quadmesh;
00101 delete major_path;
00102 delete separatrices;
00103 delete keyframes;
00104 delete vecsTime;
00105 delete vertTimeList;
00106 }
00107
00108 void TfCore::TfCoreInit(){
00109 quadmesh = new QuadMesh(NMESH, NMESH, -0.01, 1.01, -0.01, 1.01);
00110 init_majorPath();
00111 init_separatrices();
00112 init_ten_designelems();
00113 init_degpts();
00114 zoom_factor = 1;
00115 trans_x=trans_y=0;
00116 cal_inverse_transform();
00117 InitGL();
00118
00119 make_tens_Patterns();
00120 tensor_init_tex();
00121
00122 init_keyframeList();
00123 create_paraThread();
00124
00125 }
00126
00127
00128 void TfCore::makePatterns(void)
00129 {
00130 int lut[256];
00131 int phase[NPN][NPN];
00132 GLubyte pat[NPN][NPN][4];
00133 int i, j, k, t;
00134
00135 for (i = 0; i < 256; i++) lut[i] = i < 127 ? 0 : 255;
00136 for (i = 0; i < NPN; i++)
00137 for (j = 0; j < NPN; j++) phase[i][j] = rand() % 256;
00138
00139 for (k = 0; k < Npat; k++) {
00140 t = k*256/Npat;
00141 for (i = 0; i < NPN; i++)
00142 for (j = 0; j < NPN; j++) {
00143 pat[i][j][0] =
00144 pat[i][j][1] =
00145 pat[i][j][2] = lut[(t + phase[i][j]) % 255];
00146 pat[i][j][3] = alpha;
00147 }
00148 glNewList(k + 1, GL_COMPILE);
00149 glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0,
00150 GL_RGBA, GL_UNSIGNED_BYTE, pat);
00151 glEndList();
00152 }
00153 }
00154
00155
00156 void TfCore::make_tens_Patterns(void)
00157 {
00158 int lut[256];
00159 int phase[NPN][NPN];
00160 GLubyte pat[NPN][NPN][4];
00161 GLubyte spat[NPN][NPN][4];
00162 int i, j, k, t;
00163
00164 for (i = 0; i < 256; i++) lut[i] = i < 127 ? 0 : 255;
00165 for (i = 0; i < NPN; i++)
00166 for (j = 0; j < NPN; j++) phase[i][j] = rand() % 256;
00167
00168 for (k = 200; k < Npat+200; k++) {
00169
00170 for (i = 0; i < NPN; i++)
00171 for (j = 0; j < NPN; j++) {
00172 pat[i][j][0] =
00173 pat[i][j][1] =
00174 pat[i][j][2] = (GLubyte)lut[ phase[i][j] % 255];
00175 pat[i][j][3] = alpha+5;
00176
00177 spat[i][j][0] =
00178 spat[i][j][1] =
00179 spat[i][j][2] = (GLubyte)lut[ phase[i][j] % 255];
00180 spat[i][j][3] = alpha+5;
00181 }
00182
00183 glNewList(k + 1, GL_COMPILE);
00184 glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0,
00185 GL_RGBA, GL_UNSIGNED_BYTE, pat);
00186 glEndList();
00187
00188
00189 glNewList(k + 1 + 100, GL_COMPILE);
00190 glTexImage2D(GL_TEXTURE_2D, 0, 4, NPN, NPN, 0,
00191 GL_RGBA, GL_UNSIGNED_BYTE, spat);
00192 glEndList();
00193 }
00194 }
00195
00196 int TfCore::InitGL()
00197 {
00198 glViewport(0, 0, (GLsizei)REALWINSIZE, (GLsizei)REALWINSIZE);
00199 glMatrixMode(GL_PROJECTION);
00200 glLoadIdentity();
00201 gluOrtho2D(0, 1, 0, 1);
00202 glTexParameteri(GL_TEXTURE_2D,
00203 GL_TEXTURE_WRAP_S, GL_REPEAT);
00204 glTexParameteri(GL_TEXTURE_2D,
00205 GL_TEXTURE_WRAP_T, GL_REPEAT);
00206 glTexParameteri(GL_TEXTURE_2D,
00207 GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00208 glTexParameteri(GL_TEXTURE_2D,
00209 GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00210 glTexEnvf(GL_TEXTURE_ENV,
00211 GL_TEXTURE_ENV_MODE, GL_REPLACE);
00212 glEnable(GL_TEXTURE_2D);
00213 glShadeModel(GL_FLAT);
00214 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00215 glClear(GL_COLOR_BUFFER_BIT);
00216
00217 glDisable(GL_STENCIL_TEST);
00218
00219 return true;
00220 }
00221 void TfCore::init_regular_ten_designelems()
00222 {
00223
00224 if(ten_regularelems == NULL)
00225 {
00226 ten_regularelems=(TenRegularElem *)malloc(sizeof(TenRegularElem)*curMaxNumTenRegElems);
00227 if(ten_regularelems == NULL)
00228 exit(-1);
00229 }
00230 nten_regelems = 0;
00231 }
00232
00233 void TfCore::init_degpts()
00234 {
00235
00236 if(degpts!=NULL) {free(degpts); degpts=NULL;}
00237 if(degpts == NULL)
00238 {
00239 degpts = (DegeneratePt*)malloc(sizeof(DegeneratePt)*MaxNumDegeneratePts);
00240 if(degpts == NULL)
00241 exit(-1);
00242 }
00243 ndegpts = 0;
00244
00245 int i;
00246 for(i=0; i<quadmesh->nfaces; i++)
00247 {
00248 quadmesh->quadcells[i]->degpt_index = -1;
00249 }
00250 }
00251
00252
00253
00254 void TfCore::tensor_init_tex()
00255 {
00256 glDrawBuffer(GL_BACK);
00257
00258 glCallList(201);
00259
00260 glBegin(GL_QUAD_STRIP);
00261 glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
00262 glTexCoord2f(0.0, ten_dmax); glVertex2f(0.0, 1.0);
00263 glTexCoord2f(ten_dmax, 0.0); glVertex2f(1.0, 0.0);
00264 glTexCoord2f(ten_dmax, ten_dmax); glVertex2f(1.0, 1.0);
00265 glEnd();
00266
00267 glReadBuffer(GL_BACK);
00268 glReadPixels(0, 0, NPIX, NPIX, GL_RGB, GL_UNSIGNED_BYTE, major_tex1);
00269
00270 glReadBuffer(GL_BACK);
00271 glReadPixels(0, 0, NPIX, NPIX, GL_RGB, GL_UNSIGNED_BYTE, major_tex2);
00272
00273 glReadBuffer(GL_BACK);
00274 glReadPixels(0, 0, NPIX, NPIX, GL_RGB, GL_UNSIGNED_BYTE, major_tex);
00275 }
00276
00277 void TfCore::init_majorPath(){
00278 major_path=new EvenStreamlinePlace(1);
00279 major_path->setTfCore(this);
00280 major_path->init();
00281 major_path->set_default_parameters();
00282 major_path->init_major_line_info();
00283 }
00284
00285 void TfCore::init_separatrices(){
00286 separatrices=new EvenStreamlinePlace(50);
00287 separatrices->setTfCore(this);
00288 separatrices->init();
00289 separatrices->set_default_parameters();
00290 separatrices->init_major_line_info();
00291 }
00292
00293 void TfCore::cal_inverse_transform()
00294 {
00295 glMatrixMode(GL_MODELVIEW_MATRIX);
00296 glPushMatrix();
00297 glLoadIdentity();
00298 glTranslatef(-trans_x, -trans_y, 0);
00299 glTranslatef(0.5, 0.5, 0);
00300 glScalef(1./zoom_factor, 1./zoom_factor, 1./zoom_factor);
00301 glTranslatef(-.5,-.5, 0);
00302
00303 glGetFloatv(GL_MODELVIEW_MATRIX, inverse_tran);
00304
00305 glPopMatrix();
00306 }
00307
00308 void TfCore::transform_fun(){
00309 glTranslatef(trans_x, trans_y, 0);
00310 glTranslatef(0.5, 0.5, 0);
00311 glScalef(zoom_factor, zoom_factor, zoom_factor);
00312 glTranslatef(-.5,-.5, 0);
00313 }
00314
00315
00316 int TfCore::without_anti_aliasing(GLenum mode)
00317 {
00318 glClearColor(0.93, 0.93, 0.87, 1);
00319 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00320 glPushMatrix ();
00321 transform_fun();
00322 if(showIBFVOn)
00323 {
00324 glEnable(GL_TEXTURE_2D);
00325 glShadeModel(GL_FLAT);
00326
00327 render_majorfield_quad();
00328
00329 }
00330 else
00331 {
00332 glClearColor(1, 1, 1, 1);
00333 glClear(GL_COLOR_BUFFER_BIT);
00334 glDisable(GL_TEXTURE_2D);
00335 }
00336 glDisable(GL_TEXTURE_2D);
00337 glEnable(GL_COLOR_MATERIAL);
00338 glLineWidth(2.0);
00339
00340
00341 if(showRegularElemOn)
00342 display_tenRegElem(mode);
00343
00344 if(showGridOn)
00345 display_design_grid();
00346
00347 if(showSingularitiesOn)
00348 display_degenerate_pts(mode);
00349
00350 if (showMajorTenLine)
00351 display_major_tenlines(mode);
00352
00353 display_valid_trisectors(mode);
00354 display_valid_degenerate_pts(mode);
00355 display_bresenham_line();
00356
00357 display_separatrices(mode);
00358 display_trisectorVec(mode);
00359
00360 glPopMatrix ();
00361 glDisable(GL_COLOR_MATERIAL);
00362 glEnable(GL_TEXTURE_2D);
00363
00364 glFlush();
00365 return true;
00366 }
00367
00368 void TfCore::render_majorfield_quad()
00369 {
00370
00371 glMatrixMode(GL_PROJECTION);
00372 glPushMatrix();
00373 glLoadIdentity();
00374 gluOrtho2D(0, 1, 0, 1);
00375
00376 major_vis_quad();
00377
00378 glPopMatrix();
00379
00380 render_tensor_final();
00381
00382 glDisable(GL_TEXTURE_2D);
00383 }
00384
00385
00386
00387 void TfCore::render_tensor_final()
00388 {
00389
00390 glClearColor(1, 1, 1, 1);
00391 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00392
00393 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, NPIX, NPIX, 0,
00394 GL_RGB, GL_UNSIGNED_BYTE, major_tex);
00395
00396 glBegin(GL_QUAD_STRIP);
00397 glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
00398 glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 1.0);
00399 glTexCoord2f(1.0, 0.0); glVertex2f(1.0, 0.0);
00400 glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
00401 glEnd();
00402 }
00403
00404 void TfCore::major_vis_quad()
00405 {
00406
00407 glViewport(0, 0, (GLsizei)NPIX, (GLsizei)NPIX);
00408
00409
00410 glBindTexture(GL_TEXTURE_2D, tentextnames[0]);
00411 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, NPIX, NPIX, 0,
00412 GL_RGB, GL_UNSIGNED_BYTE, major_tex1);
00413
00414 render_ibfv_tens_quad(false);
00415
00416
00417 glDisable(GL_BLEND);
00418 glReadBuffer(GL_BACK);
00419 glReadPixels(0, 0, NPIX, NPIX, GL_RGB, GL_UNSIGNED_BYTE, major_tex1);
00420
00421
00422
00423
00424 major_iframe--;
00425 glBindTexture(GL_TEXTURE_2D, tentextnames[1]);
00426 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, NPIX, NPIX, 0,
00427 GL_RGB, GL_UNSIGNED_BYTE, major_tex2);
00428
00429 render_ibfv_tens_quad(true);
00430
00431 glDisable(GL_BLEND);
00432 glReadBuffer(GL_BACK);
00433 glReadPixels(0, 0, NPIX, NPIX, GL_RGB, GL_UNSIGNED_BYTE, major_tex2);
00434
00435
00436
00437
00438 int i, j;
00439 for(i=0; i<NPIX; i++)
00440 for(j=0; j<NPIX; j++)
00441 {
00442 major_temp[i][j][0] = major_tex1[i][j][0];
00443 major_temp[i][j][1] = major_tex1[i][j][1];
00444 major_temp[i][j][2] = major_tex1[i][j][2];
00445 major_temp[i][j][3] = major_alpha_map[i][j][0];
00446 }
00447
00448 for(i=0; i<NPIX; i++)
00449 for(j=0; j<NPIX; j++)
00450 {
00451 minor_temp[i][j][0] = major_tex2[i][j][0];
00452 minor_temp[i][j][1] = major_tex2[i][j][1];
00453 minor_temp[i][j][2] = major_tex2[i][j][2];
00454 minor_temp[i][j][3] = 255-major_alpha_map[i][j][0];
00455 }
00456 glEnable(GL_BLEND);
00457 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, NPIX, NPIX, 0,
00458 GL_RGBA, GL_UNSIGNED_BYTE, major_temp);
00459 render_tensor_blend();
00460 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, NPIX, NPIX, 0,
00461 GL_RGBA, GL_UNSIGNED_BYTE, minor_temp);
00462 render_tensor_blend();
00463
00465
00466 glReadBuffer(GL_BACK);
00467 glReadPixels(0, 0, NPIX, NPIX, GL_RGB, GL_UNSIGNED_BYTE, major_tex);
00468
00469 glClearColor(1, 1, 1, 1);
00470 glClear(GL_COLOR_BUFFER_BIT);
00471 glReadPixels(0, 0, NPIX, NPIX, GL_RGBA, GL_UNSIGNED_BYTE, major_temp);
00472 glReadPixels(0, 0, NPIX, NPIX, GL_RGBA, GL_UNSIGNED_BYTE, minor_temp);
00473
00474 glViewport(0, 0, (GLsizei)REALWINSIZE, (GLsizei)REALWINSIZE);
00475 }
00476 void TfCore::render_ibfv_tens_quad(bool x_y)
00477 {
00478 int i, j;
00479 QuadCell *face;
00480 QuadVertex *vert;
00481 double px, py;
00482
00483 glMatrixMode(GL_PROJECTION);
00484 glPushMatrix();
00485 glLoadIdentity();
00486 gluOrtho2D(0, 1, 0, 1);
00487 if(!x_y)
00488 {
00489 for (i=0; i<quadmesh->nfaces; i++) {
00490 face = quadmesh->quadcells[i];
00491 glBegin(GL_POLYGON);
00492 for (j=0; j<face->nverts; j++) {
00493 vert = quadmesh->quad_verts[face->verts[j]];
00494 glTexCoord2f(vert->x, vert->y);
00495
00496 if(vert->major_cos)
00497 {
00498 px = vert->x - vert->major.entry[0];
00499 py = vert->y - vert->major.entry[1];
00500 }
00501 else
00502 {
00503 px = vert->x + vert->major.entry[0];
00504 py = vert->y + vert->major.entry[1];
00505 }
00506
00507 glVertex2f(px, py);
00508 }
00509 glEnd();
00510 }
00511 }
00512 else
00513 {
00514 for (i=0; i<quadmesh->nfaces; i++) {
00515 face = quadmesh->quadcells[i];
00516 glBegin(GL_POLYGON);
00517 for (j=0; j<face->nverts; j++) {
00518 vert = quadmesh->quad_verts[face->verts[j]];
00519 glTexCoord2f(vert->x, vert->y);
00520 if(vert->major_sin)
00521 {
00522 px = vert->x - vert->major.entry[0];
00523 py = vert->y - vert->major.entry[1];
00524 }
00525 else
00526 {
00527 px = vert->x + vert->major.entry[0];
00528 py = vert->y + vert->major.entry[1];
00529 }
00530 glVertex2f(px, py);
00531 }
00532 glEnd();
00533 }
00534 }
00535 major_iframe ++;
00536
00537 glEnable(GL_BLEND);
00538
00539
00540 glCallList(major_iframe % Npat + 200+ 1);
00541
00542 glBegin(GL_QUAD_STRIP);
00543 glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
00544 glTexCoord2f(0.0, ten_tmax); glVertex2f(0.0, 1.0);
00545 glTexCoord2f(ten_tmax, 0.0); glVertex2f(1.0, 0.0);
00546 glTexCoord2f(ten_tmax, ten_tmax); glVertex2f(1.0, 1.0);
00547 glEnd();
00548
00549 glPopMatrix();
00550
00551 }
00552 void TfCore::render_tensor_blend()
00553 {
00554 glBegin(GL_QUAD_STRIP);
00555 glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
00556 glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 1.0);
00557 glTexCoord2f(1.0, 0.0); glVertex2f(1.0, 0.0);
00558 glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
00559 glEnd();
00560 }
00561 void TfCore::drawSolidRect_size(double cx, double cy, double R)
00562 {
00563 glBegin(GL_POLYGON);
00564 glVertex2f(cx-R, cy-R);
00565 glVertex2f(cx-R, cy+R);
00566 glVertex2f(cx+R, cy+R);
00567 glVertex2f(cx+R, cy-R);
00568 glEnd();
00569 }
00570 void TfCore::drawSolidCircle_size(double cx, double cy, double R)
00571 {
00572 int i;
00573 double theta, deta ;
00574 deta = 2 * M_PI/49.;
00575 double x, y;
00576 theta = 0.;
00577 glBegin(GL_POLYGON);
00578 for(i = 0; i < 50; i++, theta += deta)
00579 {
00580 x = cx + R * cos(theta);
00581 y = cy + R * sin(theta);
00582
00583 glVertex2f(x, y);
00584 }
00585 glEnd();
00586 }
00587
00589 void TfCore::display_tenRegElem(GLenum mode)
00590 {
00591 glLineWidth(1.);
00592 for(int i = 0; i < nten_regelems; i++)
00593 {
00594 if(ten_regularelems[i].ID>0)
00595 {
00597 if(mode == GL_SELECT)
00598 glLoadName(ten_regularelems[i].ID);
00599
00600 if(ten_regularelems[i].deleted)
00601 continue;
00602
00604
00605 if(ten_regularelems[i].type == 0)
00606 glColor3f(0, 1, 1);
00607 else if(ten_regularelems[i].type == 1)
00608 glColor3f(1, 0.5, 0);
00609 else
00610 glColor3f(0, 1, 0.5);
00611
00612
00613 glBegin(GL_LINES);
00614 glVertex2f(ten_regularelems[i].base[0], ten_regularelems[i].base[1]);
00615 glVertex2f(ten_regularelems[i].end[0], ten_regularelems[i].end[1]);
00616 glEnd();
00617
00618 glBegin(GL_LINES);
00619 glVertex2f(ten_regularelems[i].base[0], ten_regularelems[i].base[1]);
00620 glVertex2f(ten_regularelems[i].base[0]-ten_regularelems[i].Direct.entry[0],
00621 ten_regularelems[i].base[1]-ten_regularelems[i].Direct.entry[1]);
00622 glEnd();
00623
00624 }
00625 }
00626 }
00627
00628 void TfCore::display_trisectorVec(GLenum mode)
00629 {
00630 glLineWidth(1.5);
00631 for(int i = 0; i < validDegpts.size(); i++)
00632 {
00633 if(validDegpts[i].type==1)
00634 {
00635 for(int j=0;j<validDegpts[i].nseps;j++){
00636 if(j == 0)
00637 glColor3f(1, 0, 0);
00638 else if(j == 1)
00639 glColor3f(204.0/255, 102.0/255, 0);
00640 else
00641 glColor3f(0, 0, 1);
00642
00643 glBegin(GL_LINES);
00644 glVertex2f(validDegpts[i].gcx, validDegpts[i].gcy);
00645 glVertex2f(validDegpts[i].gcx+ validDegpts[i].s_vec[j].entry[0]*0.015, validDegpts[i].gcy+ validDegpts[i].s_vec[j].entry[1]*0.015);
00646 glEnd();
00647
00648 }
00649 }
00650 }
00651 }
00652
00653 void TfCore::display_design_grid()
00654 {
00655 glColor3f(0.8, 0.8, 0.5);
00656 glLineWidth(1.);
00657
00658 QuadCell* face;
00659 QuadVertex *v;
00660 int j;
00661 for(int i=0;i<quadmesh->nfaces;i++)
00662 {
00663 face=quadmesh->quadcells[i];
00664
00665 glBegin(GL_LINE_LOOP);
00666 for(j=0;j<face->nverts;j++)
00667 {
00668 v=quadmesh->quad_verts[face->verts[j]];
00669 glVertex2f(v->x, v->y);
00670 }
00671 glEnd();
00672 }
00673 }
00674
00675 void TfCore::display_degenerate_pts(GLenum mode)
00676 {
00677 int i, singular_id = 0;
00678
00679 for(i = 0; i < ndegpts; i++)
00680 {
00681 if(degpts[i].type == 0)
00682 glColor3f(1, 0, 0);
00683 else if(degpts[i].type == 1)
00684 glColor3f(0, 1, 0);
00685 else if(degpts[i].type == 2)
00686 glColor3f(1, 1, 0);
00687 else if(degpts[i].type == 3)
00688 glColor3f(1, 0, 1);
00689 else if(degpts[i].type == 4)
00690 glColor3f(0, 0, 1);
00691 else
00692 glColor3f(1, 1, 1);
00693
00694 drawSolidCircle_size(degpts[i].gcx, degpts[i].gcy, 0.006/zoom_factor);
00695
00696 glColor3f(0, 0, 0);
00697 glLineWidth(1.4);
00698 draw_hollow_circle_size(degpts[i].gcx, degpts[i].gcy, 0.0065/zoom_factor);
00699 }
00700 glFlush();
00701 }
00702
00703 void TfCore::draw_hollow_circle_size(double cx, double cy, double R)
00704 {
00705 int i;
00706 double theta, deta ;
00707 deta = 2 * M_PI/49.;
00708 double x, y;
00709 theta = 0.;
00710 glBegin(GL_LINE_LOOP);
00711 for(i = 0; i < 50; i++, theta += deta)
00712 {
00713 x = cx + R * cos(theta);
00714 y = cy + R * sin(theta);
00715
00716 glVertex2f(x, y);
00717 }
00718 glEnd();
00719 }
00720
00721 int TfCore::DrawGLScene(GLenum mode)
00722 {
00723 glEnable(GL_LINE_SMOOTH);
00724 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
00725 glDisable(GL_LIGHTING);
00726 without_anti_aliasing(mode);
00727 publish_image();
00728 return 1;
00729 }
00730
00731 void TfCore::set_ten_regBasis(double x, double y, int type)
00732 {
00734 if(nten_regelems >= curMaxNumTenRegElems-1 )
00735 {
00736
00737 curMaxNumTenRegElems += 50;
00738 ten_regularelems = (TenRegularElem*)realloc(ten_regularelems, sizeof(TenRegularElem) * curMaxNumTenRegElems);
00739 if(ten_regularelems == NULL)
00740 exit(-1);
00741
00742 }
00743 ten_regularelems[nten_regelems].end[0] = ten_regularelems[nten_regelems].base[0] = x;
00744 ten_regularelems[nten_regelems].end[1] = ten_regularelems[nten_regelems].base[1] = y;
00745 ten_regularelems[nten_regelems].ID = nten_regelems+1;
00746 ten_regularelems[nten_regelems].type = type;
00747 ten_regularelems[nten_regelems].Direct.set(0, 0);
00748
00750 ten_regularelems[nten_regelems].transform_matrix.setIdentity();
00751
00752
00753 ten_regularelems[nten_regelems].rotang = 0;
00754 ten_regularelems[nten_regelems].s = 1;
00755
00756 ten_regularelems[nten_regelems].deleted=false;
00757
00758
00759 ten_regularelems[nten_regelems].which_region=get_region_id(x, y);
00760
00761 nten_regelems ++;
00762 }
00763
00764
00765 unsigned char TfCore::get_region_id(double x, double y)
00766 {
00767 int i=(x-quadmesh->xstart)/quadmesh->xinterval;
00768 int j=(y-quadmesh->ystart)/quadmesh->yinterval;
00769
00770 if(i>=quadmesh->XDIM-1) i=quadmesh->XDIM-2;
00771 if(j>=quadmesh->YDIM-1) j=quadmesh->YDIM-2;
00772
00773 int cellid=j*(quadmesh->XDIM-1)+i;
00774 return quadmesh->quadcells[cellid]->which_region;
00775 }
00776
00777 void TfCore::set_ten_regDir(double x, double y)
00778 {
00780
00781 ten_regularelems[nten_regelems - 1].end[0] = x ;
00782 ten_regularelems[nten_regelems - 1].end[1] = y ;
00783
00784 ten_regularelems[nten_regelems - 1].Direct.entry[0] = x - ten_regularelems[nten_regelems - 1].base[0];
00785 ten_regularelems[nten_regelems - 1].Direct.entry[1] = y - ten_regularelems[nten_regelems - 1].base[1];
00786
00787 ten_regularelems[nten_regelems - 1].rotang =
00788 atan2(ten_regularelems[nten_regelems - 1].Direct.entry[1],
00789 ten_regularelems[nten_regelems - 1].Direct.entry[0]);
00790 }
00791
00792 void TfCore::set_ten_regDir(double x, double y,icVector2 &vec)
00793 {
00795 ten_regularelems[nten_regelems - 1].end[0] = x+vec.entry[0];
00796 ten_regularelems[nten_regelems - 1].end[1] = y+vec.entry[1] ;
00797
00798 ten_regularelems[nten_regelems - 1].Direct.entry[0] =vec.entry[0];
00799 ten_regularelems[nten_regelems - 1].Direct.entry[1] = vec.entry[1];
00800
00801 ten_regularelems[nten_regelems - 1].rotang =
00802 atan2(ten_regularelems[nten_regelems - 1].Direct.entry[1],
00803 ten_regularelems[nten_regelems - 1].Direct.entry[0]);
00804 }
00805
00806
00807 void TfCore::cal_tensorvals_quad()
00808 {
00809 int i;
00810 QuadVertex *v;
00811 double t[4]={0.};
00812
00813 for(i=0; i<quadmesh->nverts; i++)
00814 {
00815 v = quadmesh->quad_verts[i];
00816
00817 if(!v->inland)
00818 continue;
00819 get_tensor(v->x, v->y, t);
00820 v->Jacobian.entry[0][0] = t[0];
00821 v->Jacobian.entry[0][1] = t[1];
00822 v->Jacobian.entry[1][0] = t[2];
00823 v->Jacobian.entry[1][1] = t[3];
00824 }
00825 }
00826
00827
00828 void TfCore::get_tensor(double x, double y, double t[4])
00829 {
00830 int i;
00831 double dx, dy, vx, vy, t00, t01, t10, t11, r=0.;
00832 double d;
00833
00834 icMatrix3x3 tempJacobian, transposerot;
00835 double ang;
00836
00837 vx = vy = 0.;
00838
00839 t[0]=t[1]=t[2]=t[3]=0.;
00840
00842 for(i = 0; i < ntenelems; i++)
00843 {
00844 if(ten_designelems[i].ID >= 0 && !ten_designelems[i].deleted)
00845 {
00846 dx = x - ten_designelems[i].centerx;
00847 dy = y - ten_designelems[i].centery;
00848
00849 r = dx*dx + dy*dy;
00850 d = exp(-1000*r);
00851
00852 if (r < DistanceThreshold) r = DistanceThreshold;
00853
00854 tempJacobian.set(ten_designelems[i].transform_matrix);
00855
00856 ang = ten_designelems[i].rotang;
00857
00858 transposerot.set(cos(ang), sin(ang), 0,
00859 -sin(ang), cos(ang), 0,
00860 0,0,1);
00861
00862 tempJacobian.rightMultiply(transposerot);
00863
00864 if(ten_designelems[i].type == 0)
00865 {
00866 t00 = (dx * tempJacobian.entry[0][0] + dy * tempJacobian.entry[0][1])/r;
00867 t01 = (dy * tempJacobian.entry[0][0] - dx * tempJacobian.entry[0][1])/r;
00868 t10 = (dx * tempJacobian.entry[1][0] + dy * tempJacobian.entry[1][1])/r;
00869 t11 = (dy * tempJacobian.entry[1][0] - dx * tempJacobian.entry[1][1])/r;
00870 }
00871 else if(ten_designelems[i].type == 1)
00872 {
00873 t00 = (dx * tempJacobian.entry[0][0] - dy * tempJacobian.entry[0][1])/r;
00874 t01 = (-dy * tempJacobian.entry[0][0] - dx * tempJacobian.entry[0][1])/r;
00875 t10 = (dx * tempJacobian.entry[1][0] - dy * tempJacobian.entry[1][1])/r;
00876 t11 = (-dy * tempJacobian.entry[1][0] - dx * tempJacobian.entry[1][1])/r;
00877 }
00878 else if(ten_designelems[i].type == 2)
00879 {
00880 t00 = ((dx*dx-dy*dy)*tempJacobian.entry[0][0]+2*dx*dy*tempJacobian.entry[0][1])/(r*sqrt(r));
00881 t01 = (2*dx*dy*tempJacobian.entry[0][0]-(dx*dx-dy*dy)*tempJacobian.entry[0][1])/(r*sqrt(r));
00882 t10 = ((dx*dx-dy*dy)*tempJacobian.entry[1][0]+2*dx*dy*tempJacobian.entry[1][1])/(r*sqrt(r));
00883 t11 = (2*dx*dy*tempJacobian.entry[1][0]-(dx*dx-dy*dy)*tempJacobian.entry[1][1])/(r*sqrt(r));
00884
00885 }
00886 else if(ten_designelems[i].type == 3)
00887 {
00888 t00 = ((dy*dy-dx*dx)*tempJacobian.entry[0][0]-2*dx*dy*tempJacobian.entry[0][1])/(r*sqrt(r));
00889 t01 = (-2*dx*dy*tempJacobian.entry[0][0]+(dx*dx-dy*dy)*tempJacobian.entry[0][1])/(r*sqrt(r));
00890 t10 = ((dy*dy-dx*dx)*tempJacobian.entry[1][0]-2*dx*dy*tempJacobian.entry[1][1])/(r*sqrt(r));
00891 t11 = (-2*dx*dy*tempJacobian.entry[1][0]+(dx*dx-dy*dy)*tempJacobian.entry[1][1])/(r*sqrt(r));
00892 }
00893 else if(ten_designelems[i].type == 4)
00894 {
00895 t00 = ((dx*dx-dy*dy)*tempJacobian.entry[0][0]-2*dx*dy*tempJacobian.entry[0][1])/(r*sqrt(r));
00896 t01 = (-2*dx*dy*tempJacobian.entry[0][0]-(dx*dx-dy*dy)*tempJacobian.entry[0][1])/(r*sqrt(r));
00897 t10 = ((dx*dx-dy*dy)*tempJacobian.entry[1][0]-2*dx*dy*tempJacobian.entry[1][1])/(r*sqrt(r));
00898 t11 = (-2*dx*dy*tempJacobian.entry[1][0]-(dx*dx-dy*dy)*tempJacobian.entry[1][1])/(r*sqrt(r));
00899 }
00900
00901
00902
00903
00904 t[0] += t00/sqrt(r)*LOWER;
00905 t[1] += t01/sqrt(r)*LOWER;
00906 t[2] += t10/sqrt(r)*LOWER;
00907 t[3] += t11/sqrt(r)*LOWER;
00908
00909 }
00910
00911 }
00912
00913
00914
00915 for(i = 0; i < nten_regelems; i++)
00916 {
00917 if(ten_regularelems[i].ID > 0 && !ten_regularelems[i].deleted)
00918 {
00919 dx = x - ten_regularelems[i].base[0];
00920 dy = y - ten_regularelems[i].base[1];
00921
00922 r = dx*dx + dy*dy;
00923
00924 if (r < DistanceThreshold) r = DistanceThreshold;
00925
00926 if(ten_regularelems[i].type == 0)
00927 {
00928
00929 double strength = length(ten_regularelems[i].Direct);
00930
00931 t[0] += strength*cos(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00932 t[1] += strength*sin(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00933 t[2] += strength*sin(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00934 t[3] += -strength*cos(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00935
00936 }
00937
00938 }
00939
00940 else if(ten_regularelems[i].ID > 0 &&
00941 !ten_regularelems[i].deleted && ten_regularelems[i].which_region == 0)
00942 {
00943 dx = x - ten_regularelems[i].base[0];
00944 dy = y - ten_regularelems[i].base[1];
00945
00946 r = dx*dx + dy*dy;
00947
00948 if (r < DistanceThreshold) r = DistanceThreshold;
00949
00950 if(ten_regularelems[i].type == 0)
00951 {
00952
00953 double strength = length(ten_regularelems[i].Direct);
00954
00955 t[0] += strength*cos(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00956 t[1] += strength*sin(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00957 t[2] += strength*sin(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00958 t[3] += -strength*cos(2*ten_regularelems[i].rotang)/(r*sqrt(r));
00959
00960 }
00961 }
00962 }
00963
00964 }
00965
00966 void TfCore::init_ten_designelems()
00967 {
00968
00969 if(ten_designelems == NULL)
00970 {
00971 ten_designelems=(Degenerate_Design *)malloc(sizeof(Degenerate_Design)*curMaxNumTenDesignElems);
00972 if(ten_designelems == NULL)
00973 exit(-1);
00974 }
00975 ntenelems = 0;
00976
00977 init_regular_ten_designelems();
00978 }
00979
00980 void TfCore::cal_all_eigenvecs_quad()
00981 {
00982 int i;
00983
00984 for(i=0; i<quadmesh->nverts; i++)
00985 {
00986 if(quadmesh->quad_verts[i]->inland)
00987 cal_eigenvecs_onevert_quad(i);
00988 }
00989
00990
00991 normalized_tensorfield_quad();
00992 }
00993
00994 void TfCore::cal_eigenvecs_onevert_quad(int ver)
00995 {
00996 QuadVertex *v=quadmesh->quad_verts[ver];
00997 icVector2 ev[2];
00998
00999 if(fabs(v->Jacobian.entry[0][0])<=1.e-7
01000 &&fabs(v->Jacobian.entry[0][1])<=1.e-7
01001 &&fabs(v->Jacobian.entry[1][0])<=1.e-7
01002 &&fabs(v->Jacobian.entry[1][1])<=1.e-7)
01003 {
01004 v->major.set(0,0);
01005 v->minor.set(0,0);
01006 v->major_ang=0;
01007 v->minor_ang=0;
01008 return;
01009 }
01010
01011 cal_eigen_vector_sym(v->Jacobian, ev);
01012
01013 v->major = ev[0];
01014 v->minor = ev[1];
01015
01016
01017 v->major_ang = atan2(v->major.entry[1], v->major.entry[0]);
01018 v->minor_ang = atan2(v->minor.entry[1], v->minor.entry[0]);
01019
01020
01021 v->tensor_major_ang = v->major_ang;
01022
01023
01024
01025 v->tran_vec.set(cos(2*v->tensor_major_ang), sin(2*v->tensor_major_ang));
01026
01027
01028
01029 double major_ang_cos = cos(v->major_ang);
01030 double major_ang_sin = sin(v->major_ang);
01031
01032 v->major_ang = major_ang_cos*major_ang_cos;
01033 if(major_ang_cos<0)
01034 v->major_cos = true;
01035 else
01036 v->major_cos = false;
01037 if(major_ang_sin<0)
01038 v->major_sin = true;
01039 else
01040 v->major_sin = false;
01041
01042 double minor_ang_cos = cos(v->minor_ang);
01043 double minor_ang_sin = sin(v->minor_ang);
01044
01045 v->minor_ang = minor_ang_cos*minor_ang_cos;
01046
01047 if(minor_ang_cos<0)
01048 v->minor_cos = true;
01049 else
01050 v->minor_cos = false;
01051 if(minor_ang_sin<0)
01052 v->minor_sin = true;
01053 else
01054 v->minor_sin = false;
01055
01056 }
01057
01058 void TfCore::cal_eigen_vector_sym(icMatrix2x2 m, icVector2 ev[2])
01059 {
01060
01061 icMatrix2x2 dev;
01062 double half_trace = 0.5*(m.entry[0][0]+m.entry[1][1]);
01063 dev.entry[0][0] = m.entry[0][0]-half_trace;
01064 dev.entry[1][1] = m.entry[1][1]-half_trace;
01065 dev.entry[0][1] = m.entry[0][1];
01066 dev.entry[1][0] = m.entry[1][0];
01067
01068
01069 double theta = atan2(dev.entry[0][1], dev.entry[0][0]);
01070
01071
01072
01073
01074 ev[0].entry[0] = cos(theta/2.);
01075 ev[0].entry[1] = sin(theta/2.);
01076
01077
01078
01079
01080 ev[1].entry[0] = cos((theta+M_PI)/2.);
01081 ev[1].entry[1] = sin((theta+M_PI)/2.);
01082
01083
01084 }
01085
01086 void TfCore::normalized_tensorfield_quad()
01087 {
01088
01089 int i;
01090 double r;
01091 QuadVertex *cur_v;
01092
01093 for(i = 0; i < quadmesh->nverts; i++)
01094 {
01095 cur_v = quadmesh->quad_verts[i];
01096
01097
01098 r = length(cur_v->major);
01099 r *= r;
01100 if (r < DistanceThreshold)
01101 {
01102 r = DistanceThreshold;
01103 cur_v->major *= ten_dmax/r;
01104 }
01105 r = length(cur_v->major);
01106 r *= r;
01107 if (r > ten_dmax*ten_dmax) {
01108 r = sqrt(r);
01109 cur_v->major *= ten_dmax/r;
01110 }
01111
01112
01113 r = length(cur_v->minor);
01114 r *= r;
01115 if (r < DistanceThreshold)
01116 {
01117 r = DistanceThreshold;
01118 cur_v->minor *= ten_dmax/r;
01119 }
01120 r = length(cur_v->minor);
01121 r *= r;
01122 if (r > ten_dmax*ten_dmax) {
01123 r = sqrt(r);
01124 cur_v->minor *= ten_dmax/r;
01125 }
01126 }
01127 }
01128
01129 void TfCore::render_alpha_map_quad()
01130 {
01131
01132 int i, j;
01133 QuadCell *face;
01134 QuadVertex *vert;
01135
01136 glViewport(0, 0, (GLsizei)NPIX, (GLsizei)NPIX);
01137 glDisable(GL_TEXTURE_2D);
01138 glDisable(GL_BLEND);
01139 glShadeModel(GL_SMOOTH);
01140 for (i=0; i<quadmesh->nfaces; i++) {
01141 face = quadmesh->quadcells[i];
01142 glBegin(GL_POLYGON);
01143 for (j=0; j<face->nverts; j++) {
01144 vert = quadmesh->quad_verts[face->verts[j]];
01145 glColor3f(vert->major_ang,
01146 vert->major_ang,
01147 vert->major_ang);
01148
01149 glVertex2f(vert->x, vert->y);
01150 }
01151 glEnd();
01152 }
01153
01154
01155 glReadBuffer(GL_BACK);
01156 glReadPixels(0, 0, NPIX, NPIX, GL_RGB, GL_UNSIGNED_BYTE, major_alpha_map);
01157 glDisable(GL_BLEND);
01158 glViewport(0, 0, (GLsizei)REALWINSIZE, (GLsizei)REALWINSIZE);
01159 }
01160
01161
01162 void TfCore::locate_degpts_cells_tranvec_quad(void)
01163 {
01164
01165 unsigned int i, j;
01166 QuadCell *face;
01167 QuadVertex *v;
01168 icVector2 vec[4];
01169 double theta[4];
01170
01171 double vec_ang[4];
01172 double ang_sum;
01173
01175 ndegenerate_tris = 0;
01176
01177 if(degenerate_tris == NULL)
01178 degenerate_tris = (int*) malloc(sizeof(int) * MaxNumDegeneratePts);
01179
01180
01182 for (i = 0; i < quadmesh->nfaces; i++) {
01183 face = quadmesh->quadcells[i];
01184
01185 ang_sum = 0;
01186
01187 for(j=0; j<face->nverts; j++)
01188 {
01189 v = quadmesh->quad_verts[face->verts[j]];
01190 vec_ang[j] = atan2(v->tran_vec.entry[1], v->tran_vec.entry[0]);
01191 if(vec_ang[j] < 0) vec_ang[j] += 2 * M_PI;
01192 }
01193
01194 for(j = 0; j < face->nverts; j++)
01195 {
01196 theta[j] = vec_ang[(j+1)%face->nverts] - vec_ang[j];
01197
01198 if( theta[j] < -M_PI)
01199 theta[j] += 2 * M_PI;
01200
01201 if( theta[j] > M_PI)
01202 theta[j] -= 2 * M_PI;
01203
01204 ang_sum += theta[j];
01205 }
01206
01207 double index = ang_sum/(2*M_PI);
01208
01209
01210
01211 if(fabs(index) >= 1.- 1.e-1)
01212 {
01213
01214
01215 degenerate_tris[ndegenerate_tris] = i;
01216 ndegenerate_tris ++;
01217
01218 if(fabs(index-1)<1e-2)
01219 quadmesh->quadcells[i]->degenerate_type = 0;
01220 else if(fabs(index+1)<1e-2)
01221 quadmesh->quadcells[i]->degenerate_type = 1;
01222 else if(fabs(index-2)<1e-2)
01223 quadmesh->quadcells[i]->degenerate_type = 2;
01224 else if(fabs(index+2)<1e-2)
01225 quadmesh->quadcells[i]->degenerate_type = 3;
01226
01227 if(ndegenerate_tris >= MaxNumDegeneratePts - 1)
01228 {
01229 MaxNumDegeneratePts += 50;
01230 degenerate_tris = (int*) realloc(degenerate_tris, sizeof(int) * MaxNumDegeneratePts);
01231 degpts = (DegeneratePt*)realloc(degpts, sizeof(DegeneratePt)*MaxNumDegeneratePts);
01232 }
01233 }
01234 }
01235
01236 if(ndegenerate_tris>0)
01237 compute_degpts_pos_tranvec_quad();
01238 }
01239
01240
01241 void TfCore::compute_degpts_pos_tranvec_quad()
01242 {
01243 int i;
01244 double x_cp, y_cp;
01245 ndegpts = 0;
01246
01247 for(i=0; i<ndegenerate_tris; i++)
01248 {
01249 compute_onedegpt_pos_tranvec_quad(degenerate_tris[i], x_cp, y_cp);
01250
01251
01252 degpts[ndegpts].gcx = x_cp;
01253 degpts[ndegpts].gcy = y_cp;
01254 degpts[ndegpts].degpt_index = ndegpts;
01255 degpts[ndegpts].type = quadmesh->quadcells[degenerate_tris[i]]->degenerate_type;
01256 degpts[ndegpts].Triangle_ID = degenerate_tris[i];
01257 quadmesh->quadcells[degenerate_tris[i]]->degpt_index = ndegpts;
01258
01259
01260 degpts[ndegpts].nseps = 0;
01261 degpts[ndegpts].nlinks = 0;
01262 ndegpts++;
01263 }
01264
01265 }
01266 void TfCore::compute_onedegpt_pos_tranvec_quad(int cellid, double &x, double &y)
01267 {
01268
01269
01270
01271
01272
01273 QuadCell *qc = quadmesh->quadcells[cellid];
01274
01275
01276 QuadVertex *v00 = quadmesh->quad_verts[qc->verts[0]];
01277 QuadVertex *v01 = quadmesh->quad_verts[qc->verts[3]];
01278 QuadVertex *v10 = quadmesh->quad_verts[qc->verts[1]];
01279 QuadVertex *v11 = quadmesh->quad_verts[qc->verts[2]];
01280
01281 icVector2 v0v1, v2v3;
01282 double a, b;
01283
01284
01285 compute_a_alongx_degptlocate(a, v00->tran_vec, v10->tran_vec, v11->tran_vec, v01->tran_vec,
01286 v0v1, v2v3);
01287
01288
01289 if(fabs(v0v1.entry[0])>1e-8)
01290 {
01291 b = (v0v1.entry[0])/(v0v1.entry[0]-v2v3.entry[0]);
01292 }
01293 else
01294 {
01295 b = (v0v1.entry[1])/(v0v1.entry[1]-v2v3.entry[1]);
01296 }
01297 if(a<0||a>1) a=0.5;
01298 if(b<0 ||b>1)b=0.5;
01299
01300 x = bilinear_interpolate(a, b, v00->x, v01->x, v10->x, v11->x);
01301 y = bilinear_interpolate(a, b, v00->y, v01->y, v10->y, v11->y);
01302 }
01303
01304
01305 void TfCore::compute_a_alongx_degptlocate(double &a, icVector2 v0, icVector2 v1, icVector2 v2, icVector2 v3,
01306 icVector2 &v0v1, icVector2 &v2v3)
01307 {
01308
01309
01310 double a0, a1;
01311 bool orient = false;
01312 a0=0.; a1=1.;
01313 a = 0.5;
01314 v0v1 = 0.5*(v0+v1);
01315 v2v3 = 0.5*(v3+v2);
01316 double theta1, theta2, theta;
01317 double theta_v0, theta_v1, theta_v2, theta_v3, theta_v03;
01318 theta_v0 = atan2(v0.entry[1], v0.entry[0]);
01319
01320
01321
01322
01323
01324 theta_v3 = atan2(v3.entry[1], v3.entry[0]);
01325
01326
01327 theta_v03 = theta_v3-theta_v0;
01328 if(theta_v03>=0)
01329 orient = false;
01330 else
01331 orient = true;
01332 if(theta_v03<-M_PI) orient = false;
01333 if(theta_v03>M_PI) orient = true;
01334
01335
01336
01337
01338
01339 theta1 = atan2(v0v1.entry[1], v0v1.entry[0]);
01340
01341 theta2 = atan2(v2v3.entry[1], v2v3.entry[0]);
01342
01343
01344 theta = theta1-theta2;
01345
01346 bool s_orient = false;
01347 while(fabs(fabs(theta)-M_PI)>1e-8 && fabs(a0-a1)>1e-9)
01348 {
01349 if(theta>=0)
01350 s_orient = false;
01351 else
01352 s_orient = true;
01353
01354 if(theta>M_PI) s_orient = true;
01355 if(theta<-M_PI) s_orient = false;
01356
01357
01358 if((orient&&s_orient) || (!orient&&!s_orient))
01359 {
01360
01361 a1 = a;
01362 a = (a0+a1)/2.;
01363 }
01364 else
01365 {
01366
01367 a0 = a;
01368 a = (a0+a1)/2.;
01369 }
01370
01371
01372 v0v1 = (1-a)*v0+a*v1;
01373 v2v3 = (1-a)*v3+a*v2;
01374
01375
01376 theta1 = atan2(v0v1.entry[1], v0v1.entry[0]);
01377 if(theta1<0) theta1 += 2*M_PI;
01378 theta2 = atan2(v2v3.entry[1], v2v3.entry[0]);
01379 if(theta2<0) theta2 += 2*M_PI;
01380
01381 theta = theta1-theta2;
01382
01383 }
01384
01385 v0v1 = (1-a)*v0+a*v1;
01386 v2v3 = (1-a)*v3+a*v2;
01387 }
01388
01389 void TfCore::compute_separatrixVec_degpt_quad(int degpt_index)
01390 {
01391 QuadCell *face = quadmesh->quadcells[validDegpts[degpt_index].Triangle_ID];
01392 QuadVertex *v;
01393 icMatrix2x2 dv[3];
01394
01395 int i,start;
01396 icVector3 point0(quadmesh->quad_verts[face->verts[0]]->x,quadmesh->quad_verts[face->verts[0]]->y,0);
01397 icVector3 point1(quadmesh->quad_verts[face->verts[1]]->x,quadmesh->quad_verts[face->verts[1]]->y,0);
01398 icVector3 point2(quadmesh->quad_verts[face->verts[2]]->x,quadmesh->quad_verts[face->verts[2]]->y,0);
01399 icVector3 degpt_point(validDegpts[degpt_index].gcx,validDegpts[degpt_index].gcy,0);
01400 if (PointInTriangle(point0,point1,point2,degpt_point)) start=0;
01401 else start=1;
01402
01403 for(i=start; i<3+start; i++)
01404 {
01405 dv[i-start].set(0.);
01406 v=quadmesh->quad_verts[face->verts[i]];
01407 double half_trace = 0.5*(v->Jacobian.entry[0][0]+v->Jacobian.entry[1][1]);
01408 dv[i-start].entry[0][0] = v->Jacobian.entry[0][0]-half_trace;
01409 dv[i-start].entry[1][1] = v->Jacobian.entry[1][1]-half_trace;
01410 dv[i-start].entry[0][1] = v->Jacobian.entry[0][1];
01411 dv[i-start].entry[1][0] = v->Jacobian.entry[1][0];
01412 }
01413
01414
01415
01416
01417
01418
01419 double a, b, c, d, e, f;
01420 double x[3], y[3];
01421 double vx[3], vy[3];
01422
01423 for (i=start; i<3+start; i++) {
01424 v=quadmesh->quad_verts[face->verts[i]];
01425 x[i-start] = v->x;
01426 y[i-start] = v->y;
01427
01429
01430
01431 vx[i-start] = dv[i-start].entry[0][0];
01432 vy[i-start] = dv[i-start].entry[0][1];
01433
01434 }
01435
01437 double coord[3][3], *inver_coord ;
01438 for(int k = 0; k < 3; k++)
01439 {
01440 coord[0][k] = x[k];
01441 coord[1][k] = y[k];
01442 coord[2][k] = 1.;
01443 }
01444
01445 inver_coord = MatrixOpp((double*)coord, 3, 3);
01446
01447 icMatrix3x3 result, rightM;
01448 result.set(vx[0],vx[1],vx[2], vy[0],vy[1],vy[2], 1,1,1);
01449 rightM.set(inver_coord[0], inver_coord[1], inver_coord[2],
01450 inver_coord[3], inver_coord[4], inver_coord[5],
01451 inver_coord[6], inver_coord[7], inver_coord[8]);
01452
01453
01454 result.rightMultiply(rightM);
01455
01456 a = result.entry[0][0];
01457 b = result.entry[0][1];
01458 c = result.entry[0][2];
01459 d = result.entry[1][0];
01460 e = result.entry[1][1];
01461 f = result.entry[1][2];
01462
01463
01464 double solutions[4] = {0.};
01465
01466 int nroots = solve_ten_cubic_3(e, (d+2*b), (2*a-e), -d, solutions);
01467
01468 if(nroots == 0)
01469 return;
01470 else if(nroots == 1 )
01471 {
01472
01473 validDegpts[degpt_index].nseps = 1;
01474 validDegpts[degpt_index].s1_ang = atan(solutions[0]);
01475 validDegpts[degpt_index].s[0].entry[0] = cos(validDegpts[degpt_index].s1_ang);
01476 validDegpts[degpt_index].s[0].entry[1] = sin(validDegpts[degpt_index].s1_ang);
01477 }
01478 else if(nroots == 2|| nroots == 4)
01479 {
01480
01481 validDegpts[degpt_index].nseps = 2;
01482 validDegpts[degpt_index].s1_ang = atan(solutions[0]);
01483 validDegpts[degpt_index].s[0].entry[0] = cos(validDegpts[degpt_index].s1_ang);
01484 validDegpts[degpt_index].s[0].entry[1] = sin(validDegpts[degpt_index].s1_ang);
01485
01486
01487 validDegpts[degpt_index].s2_ang = atan(solutions[1]);
01488 validDegpts[degpt_index].s[1].entry[0] = cos(validDegpts[degpt_index].s2_ang);
01489 validDegpts[degpt_index].s[1].entry[1] = sin(validDegpts[degpt_index].s2_ang);
01490 }
01491 else if(nroots == 3)
01492 {
01493 validDegpts[degpt_index].nseps = 3;
01494 validDegpts[degpt_index].s1_ang = atan(solutions[0]);
01495 validDegpts[degpt_index].s[0].entry[0] = cos(validDegpts[degpt_index].s1_ang);
01496 validDegpts[degpt_index].s[0].entry[1] = sin(validDegpts[degpt_index].s1_ang);
01497
01498
01499 validDegpts[degpt_index].s2_ang = atan(solutions[1]);
01500 validDegpts[degpt_index].s[1].entry[0] = cos(validDegpts[degpt_index].s2_ang);
01501 validDegpts[degpt_index].s[1].entry[1] = sin(validDegpts[degpt_index].s2_ang);
01502
01503
01504 validDegpts[degpt_index].s3_ang = atan(solutions[2]);
01505 validDegpts[degpt_index].s[2].entry[0] = cos(validDegpts[degpt_index].s3_ang);
01506 validDegpts[degpt_index].s[2].entry[1] = sin(validDegpts[degpt_index].s3_ang);
01507
01508
01509 if(validDegpts[degpt_index].type==0){
01510 int target1=0,target2=1;
01511 float cosAngle1= fabs(dot(validDegpts[degpt_index].s[0],validDegpts[degpt_index].s[1]));
01512 float cosAngle2= fabs(dot(validDegpts[degpt_index].s[0],validDegpts[degpt_index].s[2]));
01513 float cosAngle3= fabs(dot(validDegpts[degpt_index].s[1],validDegpts[degpt_index].s[2]));
01514 if(cosAngle1>cosAngle2){
01515 target1=0;
01516 target2=2;
01517 if(cosAngle2>cosAngle3)
01518 target1=1;target2=2;
01519 }else{
01520 if(cosAngle1>cosAngle3)
01521 target1=1;target2=2;
01522 }
01523 validDegpts[degpt_index].nseps = 2;
01524 validDegpts[degpt_index].s[0]=validDegpts[degpt_index].s[target1];
01525 validDegpts[degpt_index].s[1]=validDegpts[degpt_index].s[target2];
01526 }
01527 }
01528 for(int i=0;i<3;i++)
01529 validDegpts[degpt_index].s_ifLink[i]=true;
01530 }
01531
01532
01533 void TfCore::cal_separatrix_vec(){
01534 Seed *seed1=new Seed;
01535 Seed *seed2=new Seed;
01536 float factor=0.5*1e-2;
01537 for(int i=0; i<validDegpts.size(); i++){
01538 bool ifTriSepSim=false;
01539 int target1,target2,target3;
01540 double degpt_loc[2];
01541 degpt_loc[0]=validDegpts[i].gcx;
01542 degpt_loc[1]=validDegpts[i].gcy;
01543
01544 if(validDegpts[i].type==1){
01545 if(fabs(dot(validDegpts[i].s[0],validDegpts[i].s[1]))>0.7){ifTriSepSim=true;target1=0;target2=1;target3=2;}
01546 else if(fabs(dot(validDegpts[i].s[0],validDegpts[i].s[2]))>0.7){ifTriSepSim=true;target1=0;target2=2;target3=1;}
01547 else if(fabs(dot(validDegpts[i].s[1],validDegpts[i].s[2]))>0.7){ifTriSepSim=true;target1=1;target2=2;target3=0;}
01548 }
01549 if(ifTriSepSim){
01550 seed1->pos[0]=validDegpts[i].gcx+ validDegpts[i].s[target3].entry[0]*factor;
01551 seed1->pos[1]=validDegpts[i].gcy+ validDegpts[i].s[target3].entry[1]*factor;
01552 seed1->triangle=separatrices->get_cellID_givencoords(seed1->pos[0],seed1->pos[1]);
01553
01554 seed2->pos[0]=validDegpts[i].gcx - validDegpts[i].s[target3].entry[0]*factor;
01555 seed2->pos[1]=validDegpts[i].gcy - validDegpts[i].s[target3].entry[1]*factor;
01556 seed2->triangle=separatrices->get_cellID_givencoords(seed2->pos[0],seed2->pos[1]);
01557
01558 icMatrix2x2 ten1,ten2;
01559 separatrices->compute_tensor_at_quad(seed1->triangle,seed1->pos[0], seed1->pos[1], ten1);
01560 separatrices->compute_tensor_at_quad(seed2->triangle,seed2->pos[0], seed2->pos[1], ten2);
01561 icVector2 ev1[2],ev2[2];
01562 cal_eigen_vector_sym(ten1, ev1);
01563 cal_eigen_vector_sym(ten2, ev2);
01564 double deta1=fabs(dot(ev1[0],validDegpts[i].s[target3]));
01565 double deta2=fabs(dot(ev2[0],validDegpts[i].s[target3]));
01566 if(deta1>deta2){
01567 validDegpts[i].s_vec[target3]=validDegpts[i].s[target3];
01568 }else{
01569 validDegpts[i].s_vec[target3]=-validDegpts[i].s[target3];
01570 }
01571
01572 seed1->pos[0]=validDegpts[i].gcx+ validDegpts[i].s[target1].entry[0]*factor;
01573 seed1->pos[1]=validDegpts[i].gcy+ validDegpts[i].s[target1].entry[1]*factor;
01574 seed1->triangle=separatrices->get_cellID_givencoords(seed1->pos[0],seed1->pos[1]);
01575
01576 seed2->pos[0]=validDegpts[i].gcx - validDegpts[i].s[target1].entry[0]*factor;
01577 seed2->pos[1]=validDegpts[i].gcy - validDegpts[i].s[target1].entry[1]*factor;
01578 seed2->triangle=separatrices->get_cellID_givencoords(seed2->pos[0],seed2->pos[1]);
01579
01580 separatrices->compute_tensor_at_quad(seed1->triangle,seed1->pos[0], seed1->pos[1], ten1);
01581 separatrices->compute_tensor_at_quad(seed2->triangle,seed2->pos[0], seed2->pos[1], ten2);
01582 cal_eigen_vector_sym(ten1, ev1);
01583 cal_eigen_vector_sym(ten2, ev2);
01584 deta1=fabs(dot(ev1[0],validDegpts[i].s[target1]));
01585 deta2=fabs(dot(ev2[0],validDegpts[i].s[target1]));
01586
01587 if(deta1>deta2){
01588 validDegpts[i].s_vec[target1]=validDegpts[i].s[target1];
01589 if(dot(validDegpts[i].s[target1],validDegpts[i].s[target2])>0)
01590 validDegpts[i].s_vec[target2]=-validDegpts[i].s[target2];
01591 else
01592 validDegpts[i].s_vec[target2]=validDegpts[i].s[target2];
01593 }else{
01594 validDegpts[i].s_vec[target1]=-validDegpts[i].s[target1];
01595 if(dot(validDegpts[i].s[target1],validDegpts[i].s[target2])>0)
01596 validDegpts[i].s_vec[target2]=validDegpts[i].s[target2];
01597 else
01598 validDegpts[i].s_vec[target2]=-validDegpts[i].s[target2];
01599 }
01600 }else{
01601 for(int j=0; j<validDegpts[i].nseps;j++)
01602 {
01603 seed1->pos[0]=validDegpts[i].gcx+ validDegpts[i].s[j].entry[0]*factor;
01604 seed1->pos[1]=validDegpts[i].gcy+ validDegpts[i].s[j].entry[1]*factor;
01605 seed1->triangle=separatrices->get_cellID_givencoords(seed1->pos[0],seed1->pos[1]);
01606
01607 seed2->pos[0]=validDegpts[i].gcx - validDegpts[i].s[j].entry[0]*factor;
01608 seed2->pos[1]=validDegpts[i].gcy - validDegpts[i].s[j].entry[1]*factor;
01609 seed2->triangle=separatrices->get_cellID_givencoords(seed2->pos[0],seed2->pos[1]);
01610 icMatrix2x2 ten1,ten2;
01611 separatrices->compute_tensor_at_quad(seed1->triangle,seed1->pos[0], seed1->pos[1], ten1);
01612 separatrices->compute_tensor_at_quad(seed2->triangle,seed2->pos[0], seed2->pos[1], ten2);
01613 icVector2 ev1[2],ev2[2];
01614 cal_eigen_vector_sym(ten1, ev1);
01615 cal_eigen_vector_sym(ten2, ev2);
01616 double deta1=fabs(dot(ev1[0],validDegpts[i].s[j]));
01617 double deta2=fabs(dot(ev2[0],validDegpts[i].s[j]));
01618 if(deta1>deta2){
01619 validDegpts[i].s_vec[j]=validDegpts[i].s[j];
01620 }else{
01621 validDegpts[i].s_vec[j]=-validDegpts[i].s[j];
01622 }
01623 }
01624 }
01625 }
01626 }
01627
01628
01629
01630
01631
01632 void TfCore::gen_separatrix(){
01633 reset_separatrices();
01634 double degpt_loc[2];
01635 double startpt[2];
01636 int startcell;
01637 int fieldtype;
01638 fieldtype=0;
01639 float factor=1e-2;
01640 for(int i=0; i<validDegpts.size(); i++)
01641 {
01642 if(validDegpts[i].type==1){
01643 for(int j=0; j<validDegpts[i].nseps;j++)
01644 {
01645 degpt_loc[0]=validDegpts[i].gcx;
01646 degpt_loc[1]=validDegpts[i].gcy;
01647 startpt[0]=validDegpts[i].gcx+ validDegpts[i].s_vec[j].entry[0]*factor;
01648 startpt[1]=validDegpts[i].gcy+ validDegpts[i].s_vec[j].entry[1]*factor;
01649 startcell=separatrices->get_cellID_givencoords(startpt[0],startpt[1]);
01650 separatrices->grow_a_separatrix(degpt_loc,startpt, startcell, separatrices->percentage_dsep*separatrices->dsep,
01651 separatrices->discsize, separatrices->sample_interval, separatrices->loopdsep, separatrices->dist2sing,
01652 separatrices->streamlinelength, fieldtype,validDegpts[i].s_vec[j],i,j);
01653 }
01654 }
01655 }
01656
01657 }
01658
01659 void TfCore::display_major_tenlines(GLenum mode)
01660 {
01661 if(major_path == NULL)
01662 return;
01663 int i, j, k;
01664 Trajectory *cur_traj;
01665 glColor3f(1, 0, 0);
01666 glLineWidth(1.5);
01667 cur_traj = major_path->evenstreamlines->trajs[0];
01668
01669 for(k=0; k<cur_traj->nlinesegs; k++)
01670 {
01671 glBegin(GL_LINES);
01672 glVertex2f(cur_traj->linesegs[k].gstart[0], cur_traj->linesegs[k].gstart[1]);
01673 glVertex2f(cur_traj->linesegs[k].gend[0], cur_traj->linesegs[k].gend[1]);
01674 glEnd();
01675 }
01676 glFlush();
01677 }
01678
01679 void TfCore::display_separatrices(GLenum mode){
01680 if(separatrices == NULL)
01681 return;
01682 int i, j, k;
01683 Trajectory *cur_traj;
01684 glColor3f(0, 1, 0);
01685 glLineWidth(1.5);
01686 glShadeModel(GL_SMOOTH);
01687 for(j=0; j<separatrices->evenstreamlines->ntrajs; j++)
01688 {
01689 cur_traj = separatrices->evenstreamlines->trajs[j];
01690 glColor3f(1, 1, 0);
01691 drawSolidCircle_size(cur_traj->linesegs[0].gend[0], cur_traj->linesegs[0].gend[1], 0.003/zoom_factor);
01692 glColor3f(0, 1, 0);
01693 for(k=0; k<cur_traj->nlinesegs; k++)
01694 {
01695 glBegin(GL_LINES);
01696 glVertex2f(cur_traj->linesegs[k].gstart[0], cur_traj->linesegs[k].gstart[1]);
01697 glVertex2f(cur_traj->linesegs[k].gend[0], cur_traj->linesegs[k].gend[1]);
01698 glEnd();
01699 }
01700 }
01701 glFlush();
01702 }
01703
01704 void TfCore::reset_major_path(){
01705 free(major_path);
01706 init_majorPath();
01707 }
01708
01709 void TfCore::reset_separatrices(){
01710 free(separatrices);
01711 init_separatrices();
01712 }
01713
01714 void TfCore::set_robot_loc(double x,double y){
01715 robot_loc->pos[0]=x;
01716 robot_loc->pos[1]=y;
01717 }
01718
01719 void TfCore::gen_major_path(){
01720 listen_to_robot_loc();
01721 double startpt[2];
01722 int startcell;
01723 robot_loc->triangle=major_path->get_cellID_givencoords(robot_loc->pos[0],robot_loc->pos[1]);
01724 startcell=robot_loc->triangle;
01725 startpt[0]=robot_loc->pos[0];
01726 startpt[1]=robot_loc->pos[1];
01727 major_path->grow_a_majRoad(startpt, startcell, major_path->percentage_dsep*major_path->dsep,
01728 major_path->discsize, major_path->sample_interval, major_path->loopdsep, major_path->dist2sing,
01729 major_path->streamlinelength, 0,m_robotDirect);
01730 }
01731
01732
01733 void TfCore::listen_to_robot_loc(){
01734 tf::StampedTransform transform;
01735 try{
01736 ros::Time now = ros::Time::now();
01737 listener.waitForTransform(worldFrameId, baseFrameId,
01738 now, ros::Duration(3.0));
01739 listener.lookupTransform(worldFrameId, baseFrameId,
01740 now, transform);
01741 }
01742 catch (tf::TransformException ex){
01743 ROS_ERROR("%s",ex.what());
01744 }
01745 robot_world_pos[0]=transform.getOrigin().x();
01746 robot_world_pos[1]=transform.getOrigin().y();
01747
01748 double loc_x=transform.getOrigin().x()/realWorld_to_field_scale+realWorld_to_field_offset_x;
01749 double loc_y=transform.getOrigin().y()/realWorld_to_field_scale+realWorld_to_field_offset_y;
01750 set_robot_loc(loc_x,loc_y);
01751
01752 double x = transform.getRotation().getX();
01753 double y = transform.getRotation().getY();
01754 double z = transform.getRotation().getZ();
01755 double w = transform.getRotation().getW();
01756 double robot_angel = atan2(2 * (w * z + x * y), 1 - 2 * (y * y + z * z));
01757 m_robotDirect.entry[0]=cos(robot_angel);
01758 m_robotDirect.entry[1]=sin(robot_angel);
01759 }
01761
01762 void TfCore::add_separatrix_points_toRobot(Trajectory * target_traj){
01763 nav_msgs::Path path;
01764 path.header.frame_id=worldFrameId;
01765 Trajectory *cur_traj=target_traj;
01766 for (int i=0;i<cur_traj->nlinesegs;i++)
01767 {
01768 geometry_msgs::PoseStamped pose;
01769 pose.header.stamp = ros::Time::now();
01770 double x=(cur_traj->linesegs[i].gend[0]-realWorld_to_field_offset_x)*realWorld_to_field_scale;
01771 double y=(cur_traj->linesegs[i].gend[1]-realWorld_to_field_offset_y)*realWorld_to_field_scale;
01772 pose.pose.position.x=x;
01773 pose.pose.position.y=y;
01774 pose.header.frame_id=worldFrameId;
01775 pose.pose.position.z=0;
01776 pose.pose.orientation.x=0;
01777 pose.pose.orientation.y=0;
01778 pose.pose.orientation.z=0;
01779 pose.pose.orientation.w=1;
01780 path.poses.push_back(pose);
01781 }
01782 pure_pursuit_controller::executePath srv;
01783 srv.request.curPath=path;
01784 srv.request.ifFirstPoint=true;
01785 if(pathExecuteClient.call(srv)){
01786 ROS_INFO("Reach a trisector, request execute a branch");
01787 sleep(3);
01788 }
01789 else{
01790 ROS_ERROR("Failed to call service execute_path");
01791 }
01792 }
01793
01794
01795 void TfCore::add_robot_wayPoints()
01796 {
01797 Trajectory *cur_traj=major_path->evenstreamlines->trajs[0];
01798 icVector2 tmp_path_dir(cur_traj->linesegs[6].gend[0]-cur_traj->linesegs[6].gstart[0],cur_traj->linesegs[6].gend[1]-cur_traj->linesegs[6].gstart[1]);
01799 normalize(tmp_path_dir);
01800 nav_msgs::Path path;
01801 path.header.frame_id=worldFrameId;
01802 for (int i=0;i<cur_traj->nlinesegs;i++)
01803 {
01804 geometry_msgs::PoseStamped pose;
01805 pose.header.stamp = ros::Time::now();
01806 double x=(cur_traj->linesegs[i].gend[0]-realWorld_to_field_offset_x)*realWorld_to_field_scale;
01807 double y=(cur_traj->linesegs[i].gend[1]-realWorld_to_field_offset_y)*realWorld_to_field_scale;
01808 pose.pose.position.x=x;
01809 pose.pose.position.y=y;
01810 pose.header.frame_id=worldFrameId;
01811 pose.pose.position.z=0;
01812 pose.pose.orientation.x=0;
01813 pose.pose.orientation.y=0;
01814 pose.pose.orientation.z=0;
01815 pose.pose.orientation.w=1;
01816 path.poses.push_back(pose);
01817 }
01818 pure_pursuit_controller::executePath srv;
01819 srv.request.curPath=path;
01820 normalize(m_robotDirect);
01821 if(dot(m_robotDirect,tmp_path_dir)<0.34)
01822 srv.request.ifFirstPoint=true;
01823 else
01824 srv.request.ifFirstPoint=false;
01825 if(pathExecuteClient.call(srv)){
01826 ROS_INFO("Request execute path");
01827 }
01828 else{
01829 ROS_ERROR("Failed to call service execute_path");
01830 }
01831 }
01832
01833 void TfCore::cancelPath(){
01834 pure_pursuit_controller::cancelPath srv;
01835 srv.request.req="cancel";
01836 if(pathCancelClient.call(srv)){
01837 ROS_INFO("Request cancel path");
01838 }
01839 else{
01840 ROS_ERROR("Failed to call service cancel_path");
01841 }
01842 }
01843
01844
01845 void TfCore::setRegularElems(){
01846 constraints_vecs.clear();
01847
01848 for(int i=0;i<contours2Field.size();i++)
01849 {
01850 if (contours2Field[i].size()<10)
01851 continue;
01852 std::vector<icVector2> cur_vecs;
01853 for (int j=0;j<contours2Field[i].size();j++)
01854 {
01855 if(j<contours2Field[i].size()-1){
01856 std::vector<cv::Point2f> points;
01857 icVector2 tmp_dir(contours2Field[i][j+1].x-contours2Field[i][j].x,contours2Field[i][j+1].y-contours2Field[i][j].y);
01858 float cur_strength=length(tmp_dir);
01859 if(j<3){
01860 for(int k=0;k<5;k++)
01861 points.push_back(cv::Point2f(contours2Field[i][k].x,contours2Field[i][k].y));
01862 }else if(j>contours2Field[i].size()-6){
01863 for(int k=contours2Field[i].size()-5;k<contours2Field[i].size();k++)
01864 points.push_back(cv::Point2f(contours2Field[i][k].x,contours2Field[i][k].y));
01865 }else{
01866 for(int k=j-2;k<j+3;k++)
01867 points.push_back(cv::Point2f(contours2Field[i][k].x,contours2Field[i][k].y));
01868 }
01869 cv::Vec4f line;
01870 cv::fitLine(cv::Mat(points), line, CV_DIST_L2, 0, 0.01, 0.01);
01871 icVector2 tmp_vec(line[0],line[1]);
01872 if(dot(tmp_vec,tmp_dir)<0) tmp_vec=-tmp_vec;
01873 tmp_vec=tmp_vec*cur_strength;
01874 cur_vecs.push_back(tmp_vec);
01875 }else
01876 {
01877 std::vector<cv::Point2f> points;
01878 icVector2 testEnd2start=(contours2Field[i][0].x-contours2Field[i][j].x,contours2Field[i][0].y-contours2Field[i][j].y);
01879 icVector2 tmp_dir;
01880 float cur_strength;
01881 if(length(testEnd2start)<0.015)
01882 {
01883 tmp_dir=testEnd2start;
01884 cur_strength=length(tmp_dir);
01885 points.push_back(cv::Point2f(contours2Field[i][0].x,contours2Field[i][0].y));
01886 points.push_back(cv::Point2f(contours2Field[i][j].x,contours2Field[i][j].y));
01887 points.push_back(cv::Point2f(contours2Field[i][j-1].x,contours2Field[i][j-1].y));
01888 }else{
01889 tmp_dir=(contours2Field[i][j].x-contours2Field[i][j-1].x,contours2Field[i][j].y-contours2Field[i][j-1].y);
01890 cur_strength=length(tmp_dir);
01891 points.push_back(cv::Point2f(contours2Field[i][j].x,contours2Field[i][j].y));
01892 points.push_back(cv::Point2f(contours2Field[i][j-1].x,contours2Field[i][j-1].y));
01893 points.push_back(cv::Point2f(contours2Field[i][j-2].x,contours2Field[i][j-2].y));
01894 }
01895 cv::Vec4f line;
01896 cv::fitLine(cv::Mat(points), line, CV_DIST_L2, 0, 0.01, 0.01);
01897 icVector2 tmp_vec(line[0],line[1]);
01898 if(dot(tmp_vec,tmp_dir)<0) tmp_vec=-tmp_vec;
01899 tmp_vec=tmp_vec*cur_strength;
01900 cur_vecs.push_back(tmp_vec);
01901
01902 }
01903
01904
01905 }
01906 constraints_vecs.push_back(cur_vecs);
01907 }
01908
01909 int count=0;
01910 for(int i=0;i<contours2Field.size();i++)
01911 {
01912 if (contours2Field[i].size()<10)
01913 continue;
01914 for (int j=0;j<contours2Field[i].size()-1;j++)
01915 {
01916 set_ten_regBasis(contours2Field[i][j].x, contours2Field[i][j].y,0);
01917 set_ten_regDir(contours2Field[i][j].x,contours2Field[i][j].y,constraints_vecs[count][j]);
01918 }
01919 count++;
01920 }
01921
01922 }
01923
01924
01925 void TfCore::goTri_callback(const std_msgs::String &msg){
01926 ifFinish_goTri=true;
01927 }
01928
01929
01930 void TfCore::gridMap_callback(const nav_msgs::OccupancyGrid &msg){
01931 if(!isReceiveNewMap)
01932 isReceiveNewMap=true;
01933 dirMap.info=msg.info;
01934 dirMap.info.width=dirMap.info.width+2;
01935 dirMap.info.height=dirMap.info.height+2;
01936 dirMap.info.origin.position.x=dirMap.info.origin.position.x-dirMap.info.resolution*0.5;
01937 dirMap.info.origin.position.y=dirMap.info.origin.position.y-dirMap.info.resolution*0.5;
01938 dirMap.data.clear();
01939 for(int i=dirMap.info.height-1;i>=0;i--)
01940 for(int j=0; j<dirMap.info.width;j++){
01941 if(i>0 && i<dirMap.info.height-1 && j>0 && j<dirMap.info.width-1){
01942 if (msg.data[msg.info.width*(i-1)+j-1]>50)
01943 dirMap.data.push_back(100);
01944 else
01945 dirMap.data.push_back(0);
01946 }else
01947 dirMap.data.push_back(0);
01948 }
01949 for(int i=0;i<dirMap.info.height;i++){
01950 for(int j=0;j<dirMap.info.width;j++){
01951 if(dirMap.data[i*dirMap.info.width+j]==100)
01952 {
01953 int x_min=max(j-2,0); int x_max=min(dirMap.info.width-1,j+2);
01954 int y_min=max(i-2,0); int y_max=min(dirMap.info.height-1,i+2);
01955 for(int l=y_min;l<=y_max;l++){
01956 for(int n=x_min;n<=x_max;n++)
01957 dirMap.data[l*dirMap.info.width+n]==100;
01958 }
01959 }
01960 }
01961 }
01962 get_obstacles_contour();
01963 ensure_robot_safety();
01964 }
01965
01966 void TfCore::frontier_point_callback(const std_msgs::Float64MultiArray &msg){
01967 frontierPoints=msg;
01968 }
01969
01970
01971 void TfCore::set_obstacles(){
01972
01973 reset_regular_and_degenrateElem();
01974 bresenham_line_points.clear();
01975 validTriDegpts.clear();
01976 ifCancelPath=false;
01977
01978 setRegularElems();
01979 parallel_update_tensorField();
01980 init_degpts();
01981 render_alpha_map_quad();
01982 locate_degpts_cells_tranvec_quad();
01983
01984 NUM_Slices+=interFrameNum;
01985 set_cur_as_keyframe(NUM_Slices);
01986 listen_to_robot_loc();
01987
01988 if(enRelaxKeyframeOn)
01989 Laplace_relax_timeDep();
01990
01991
01992 if(major_path->evenstreamlines->ntrajs!=0 && ifReachTrisector && check_reach_trisector()){
01993 reset_major_path();
01994 gen_separatrix();
01995 cal_sep_infoGain();
01996 select_target_trisector_branch_move();
01997 }else{
01998 reset_separatrices();
01999 ifReachTrisector=false;
02000 reset_major_path();
02001 gen_major_path();
02002 cut_robot_path();
02003 if(reGenPath)
02004 {
02005 reset_major_path();
02006 gen_major_path();
02007 cut_robot_path();
02008 }
02009 reGenPath=false;
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021 add_robot_wayPoints();
02022 }
02023 curSliceID=keyframes->keyframes[keyframes->nkeyframes-2]->keyFrameID+1;
02024 play_all_frames();
02025 }
02026
02027
02028 void TfCore::play_all_frames()
02029 {
02030 int t=0;
02031 while(t<interFrameNum)
02032 {
02033 ros::spinOnce();
02034 ifFinish_goTri=false;
02035 update_tensor_field();
02036 filterDegpts();
02037 cal_separatrix_vec();
02038 if(!ifReachTrisector)
02039 {
02040 if(check_bypass_trisector())
02041 return;
02042 }
02043 if(ifReachTrisector)
02044 {
02045 gen_separatrix();
02046 cal_sep_infoGain();
02047
02048 }
02049 DrawGLScene(GL_RENDER);
02050 usleep(interFrameTime*1000000);
02051
02052 t++;
02053 }
02054 }
02055
02056
02057
02058
02059 bool TfCore::check_bypass_trisector(){
02060 validTriDegpts.clear();
02061 std::vector<DegeneratePt> tmp_validTriDegpts;
02062 bresenham_line_points.clear();
02063 std::vector<float> all_min_dists;
02064 std::vector<int > all_indexes;
02065 if(major_path->evenstreamlines->ntrajs==0) return false;
02066 Trajectory *cur_traj= major_path->evenstreamlines->trajs[0];
02067 for(int i=0;i<validDegpts.size();i++){
02068 if(validDegpts[i].type==1 && validDegpts[i].nseps==3){
02069 float cur_min_dist=std::numeric_limits<float>::max();
02070 int target_min_index=-1;
02071 for(int j=0;j<cur_traj->nlinesegs;j++){
02072 float deta_x=cur_traj->linesegs[j].gstart[0]-validDegpts[i].gcx;
02073 float deta_y=cur_traj->linesegs[j].gstart[1]-validDegpts[i].gcy;
02074 float dist=sqrt(pow(deta_x,2)+pow(deta_y,2));
02075 if(dist<cur_min_dist)
02076 {
02077 target_min_index=j;
02078 cur_min_dist=dist;
02079 }
02080 }
02081 if(target_min_index>6 && target_min_index<cur_traj->nlinesegs-6){
02082
02083 std::vector<cv::Point2f> in_points;
02084 for(int k=target_min_index-6;k<=target_min_index-4;k++)
02085 in_points.push_back(cv::Point2f(cur_traj->linesegs[k].gstart[0],cur_traj->linesegs[k].gstart[1]));
02086 cv::Vec4f in_line;
02087 cv::fitLine(cv::Mat(in_points),in_line,CV_DIST_L2,0,0.01,0.01);
02088 icVector2 in_dir(in_line[0],in_line[1]);
02089 icVector2 tmp_in_dir(cur_traj->linesegs[target_min_index-6].gend[0]-cur_traj->linesegs[target_min_index-6].gstart[0],cur_traj->linesegs[target_min_index-6].gend[1]-cur_traj->linesegs[target_min_index-6].gstart[1]);
02090 if(dot(in_dir,tmp_in_dir)<0) in_dir=-in_dir;
02091 normalize(in_dir);
02092
02093 std::vector<cv::Point2f> out_points;
02094 for(int k=target_min_index+4;k<=target_min_index+6;k++)
02095 out_points.push_back(cv::Point2f(cur_traj->linesegs[k].gstart[0],cur_traj->linesegs[k].gstart[1]));
02096 cv::Vec4f out_line;
02097 cv::fitLine(cv::Mat(out_points),out_line,CV_DIST_L2,0,0.01,0.01);
02098 icVector2 out_dir(out_line[0],out_line[1]);
02099 icVector2 tmp_out_dir(cur_traj->linesegs[target_min_index+6].gend[0]-cur_traj->linesegs[target_min_index+6].gstart[0],cur_traj->linesegs[target_min_index+6].gend[1]-cur_traj->linesegs[target_min_index+6].gstart[1]);
02100 if(dot(out_dir,tmp_out_dir)<0) out_dir=-out_dir;
02101 normalize(out_dir);
02102
02103 int target_in_sep=-1;
02104 int target_out_sep=-1;
02105 float cur_in_dir_dot_min=std::numeric_limits<float>::max();
02106 float cur_out_dir_dot_max=std::numeric_limits<float>::min();
02107 for(int k=0;k<validDegpts[i].nseps;k++){
02108 if(dot(validDegpts[i].s_vec[k],in_dir)<cur_in_dir_dot_min){
02109 cur_in_dir_dot_min=dot(validDegpts[i].s_vec[k],in_dir);
02110 target_in_sep=k;
02111 }
02112 if(dot(validDegpts[i].s_vec[k],out_dir)>cur_out_dir_dot_max) {
02113 cur_out_dir_dot_max=dot(validDegpts[i].s_vec[k],out_dir);
02114 target_out_sep=k;
02115 }
02116 }
02117 if(cur_out_dir_dot_max>0.7 && cur_in_dir_dot_min<-0.7 && target_in_sep!=target_out_sep && cur_min_dist*realWorld_to_field_scale<0.8){
02118 tmp_validTriDegpts.push_back(validDegpts[i]);
02119 all_min_dists.push_back(cur_min_dist);
02120 all_indexes.push_back(i);
02121 }
02122 }
02123 }
02124 }
02125 if(tmp_validTriDegpts.size()>=1){
02126 auto smallest = std::min_element(std::begin(all_min_dists), std::end(all_min_dists));
02127 int smallest_index=std::distance(std::begin(all_min_dists),smallest);
02128 int target_tri_index=all_indexes[smallest_index];
02129
02130
02131 cv::Point2i target_tri_loc, robot_cur_loc;
02132 double target_tri_pos[2],robot_cur_pos[2];
02133 target_tri_pos[0]=validDegpts[target_tri_index].gcx;
02134 target_tri_pos[1]=validDegpts[target_tri_index].gcy;
02135 selected_target_tri=target_tri_index;
02136 locat_point_inMap(target_tri_pos,target_tri_loc);
02137 listen_to_robot_loc();
02138 robot_cur_pos[0]=robot_loc->pos[0];
02139 robot_cur_pos[1]=robot_loc->pos[1];
02140
02141 locat_point_inMap(robot_cur_pos,robot_cur_loc);
02142 bresenham_line_points.clear();
02143 CalcBresenhamLocs(Location(target_tri_loc.x,target_tri_loc.y),Location(robot_cur_loc.x,robot_cur_loc.y),bresenham_line_points);
02144 if(check_line_insect_obstacle())
02145 bresenham_line_points.clear();
02146 else{
02147 validTriDegpts.push_back(validDegpts[target_tri_index]);
02148 nav_msgs::Path path;
02149 path.header.frame_id=worldFrameId;
02150 geometry_msgs::PoseStamped pose;
02151 pose.header.stamp = ros::Time::now();
02152 if( bresenham_line_points[0].x<robot_cur_loc.x+2 && bresenham_line_points[0].x>robot_cur_loc.x-2&& bresenham_line_points[0].y<robot_cur_loc.y+2 && bresenham_line_points[0].y>robot_cur_loc.y-2)
02153 {
02154 std::vector<Location>::iterator cur_iter;
02155 for(cur_iter=bresenham_line_points.begin();cur_iter!=bresenham_line_points.end();cur_iter++){
02156 geometry_msgs::PoseStamped pose;
02157 pose.header.stamp = ros::Time::now();
02158 double x=dirMap.info.resolution*((*cur_iter).y+0.5)+dirMap.info.origin.position.x;
02159 double y=dirMap.info.resolution*(dirMap.info.height-1-(*cur_iter).x+0.5)+dirMap.info.origin.position.y;
02160 pose.pose.position.x=x;
02161 pose.pose.position.y=y;
02162 pose.header.frame_id=worldFrameId;
02163 pose.pose.position.z=0;
02164 pose.pose.orientation.x=0;
02165 pose.pose.orientation.y=0;
02166 pose.pose.orientation.z=0;
02167 pose.pose.orientation.w=1;
02168 path.poses.push_back(pose);
02169 }
02170
02171 }else{
02172 std::vector<Location>::reverse_iterator cur_iter;
02173 for(cur_iter=bresenham_line_points.rbegin();cur_iter!=bresenham_line_points.rend();cur_iter++){
02174 geometry_msgs::PoseStamped pose;
02175 pose.header.stamp = ros::Time::now();
02176 double x=dirMap.info.resolution*((*cur_iter).y+0.5)+dirMap.info.origin.position.x;
02177 double y=dirMap.info.resolution*(dirMap.info.height-1-(*cur_iter).x+0.5)+dirMap.info.origin.position.y;
02178 pose.pose.position.x=x;
02179 pose.pose.position.y=y;
02180 pose.header.frame_id=worldFrameId;
02181 pose.pose.position.z=0;
02182 pose.pose.orientation.x=0;
02183 pose.pose.orientation.y=0;
02184 pose.pose.orientation.z=0;
02185 pose.pose.orientation.w=1;
02186 path.poses.push_back(pose);
02187 }
02188
02189 }
02190
02191 pure_pursuit_controller::executePath srv;
02192 srv.request.curPath=path;
02193 srv.request.ifFirstPoint=true;
02194 if(goTriExecuteclient.call(srv)){
02195 DrawGLScene(GL_RENDER);
02196 ROS_INFO("Request go to the trisectror");
02197 while(!ifFinish_goTri){
02198 sleep(2);
02199 ros::spinOnce();
02200 if(ifCancelPath)
02201 break;
02202
02203 }
02204 ROS_INFO("go to the trisectror finish");
02205 bresenham_line_points.clear();
02206 ifFinish_goTri=false;
02207 ifReachTrisector=true;
02208 return true;
02209 }
02210 else{
02211 ROS_ERROR("Failed to call service go to the trisectror");
02212 }
02213 }
02214 }
02215 return false;
02216
02217
02218 }
02219
02220 void TfCore::draw_map_contour(){
02221 glColor3f(1, 0, 0);
02222 glLineWidth(1);
02223 for(int i=0;i<contours2Field.size();i++)
02224 {
02225 for (int j=0;j<contours2Field[i].size()-1;j++)
02226 {
02227 glBegin(GL_LINES);
02228 glVertex2f(contours2Field[i][j].x, contours2Field[i][j].y);
02229 glVertex2f(contours2Field[i][j+1].x, contours2Field[i][j+1].y);
02230 glEnd();
02231 }
02232 }
02233
02234 }
02235
02236
02237 void TfCore::get_obstacles_contour(){
02238 cv::Mat img = cv::Mat::zeros(dirMap.info.height, dirMap.info.width, CV_8UC1);
02239 dirMap2Field.clear();
02240 dirMapInWorld.clear();
02241 for (unsigned i=0;i<dirMap.info.height;i++)
02242 {
02243 std::vector<cv::Point2f> tmp_world,tmp_field;
02244 for(unsigned j=0;j<dirMap.info.width;j++)
02245 {
02246 cv::Point2f tmp_world_point,tmp_field_point;
02247 tmp_world_point.x=dirMap.info.resolution*(j+0.5)+dirMap.info.origin.position.x;
02248 tmp_world_point.y=dirMap.info.resolution*(dirMap.info.height-1-i+0.5)+dirMap.info.origin.position.y;
02249 tmp_world.push_back(tmp_world_point);
02250 tmp_field_point.x=tmp_world_point.x/realWorld_to_field_scale+realWorld_to_field_offset_x;
02251 tmp_field_point.y=tmp_world_point.y/realWorld_to_field_scale+realWorld_to_field_offset_y;
02252 if(i==0 && j==dirMap.info.width-1){
02253 rightTop[0]=tmp_field_point.x;
02254 rightTop[1]=tmp_field_point.y;
02255 }
02256 tmp_field.push_back(tmp_field_point);
02257 if(dirMap.data[dirMap.info.width*i+j]==100)
02258 img.at<uchar>(i,j)=255;
02259 else
02260 img.at<uchar>(i,j)=0;
02261 }
02262 dirMapInWorld.push_back(tmp_world);
02263 dirMap2Field.push_back(tmp_field);
02264 }
02265 leftBottom[0]=dirMap.info.origin.position.x/realWorld_to_field_scale+realWorld_to_field_offset_x;
02266 leftBottom[1]=dirMap.info.origin.position.y/realWorld_to_field_scale+realWorld_to_field_offset_y;
02267
02268 contours.clear();
02269 std::vector<cv::Vec4i> hierarchy;
02270 cv::findContours(img, contours, hierarchy, CV_RETR_LIST, cv::CHAIN_APPROX_NONE);
02271 contours2Field.clear();
02272 contoursInWorld.clear();
02273 for( size_t k = 0; k < contours.size(); k++ )
02274 {
02275 std::vector<cv::Point2f> tmp_contour_to_field,tmp_contour_in_world;
02276 for(size_t i=0;i< contours[k].size();i++){
02277 tmp_contour_to_field.push_back(dirMap2Field[contours[k][i].y][contours[k][i].x]);
02278 tmp_contour_in_world.push_back(dirMapInWorld[contours[k][i].y][contours[k][i].x]);
02279 }
02280 contours2Field.push_back(tmp_contour_to_field);
02281 contoursInWorld.push_back(tmp_contour_in_world);
02282 }
02283 }
02284
02285
02286 void TfCore::cut_robot_path(){
02287 if(major_path->evenstreamlines->ntrajs==0) return;
02288 Trajectory *cur_traj = major_path->evenstreamlines->trajs[0];
02289 int Num=500;
02290 int maxNum=Num;
02291 if(maxNum>cur_traj->nlinesegs)
02292 maxNum=cur_traj->nlinesegs;
02293 bool is_turn_sharp=false;
02294 for (int k=0;k<maxNum;k++){
02295 for(int i=0;i<contours2Field.size();i++)
02296 {
02297 for (int j=0;j<contours2Field[i].size();j++)
02298 {
02299 double x_dist=cur_traj->linesegs[k].gstart[0]-contours2Field[i][j].x;
02300 double y_dist=cur_traj->linesegs[k].gstart[1]-contours2Field[i][j].y;
02301 if(!is_turn_sharp && k>1){
02302 icVector2 now(cur_traj->linesegs[k].gend[0]-cur_traj->linesegs[k].gstart[0],cur_traj->linesegs[k].gend[1]-cur_traj->linesegs[k].gstart[1]);
02303 icVector2 pre(cur_traj->linesegs[k-1].gend[0]-cur_traj->linesegs[k-1].gstart[0],cur_traj->linesegs[k-1].gend[1]-cur_traj->linesegs[k-1].gstart[1]);
02304 normalize(now);
02305 normalize(pre);
02306 if(dot(now,pre)<0.10)
02307 {
02308 is_turn_sharp=true;
02309 cur_traj->nlinesegs=k-1;
02310 }
02311 }
02312 double cur_dist=sqrt(x_dist*x_dist+y_dist*y_dist);
02313 cur_dist=cur_dist*realWorld_to_field_scale;
02314 if (cur_dist<DANGERDIST)
02315 {
02316 reGenPath=true;
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345 return;
02346 }
02347 }
02348 }
02349 }
02350 }
02351
02352
02353 void TfCore::cal_sep_infoGain(){
02354 degptsPathsInfoGain.clear();
02355 float *pointCollection=new float[frontierPoints.data.size()];
02356 for(int i=0;i<frontierPoints.data.size();i++)
02357 pointCollection[i]=frontierPoints.data[i];
02358 for(int i=0;i<separatrices->evenstreamlines->ntrajs;i++){
02359 Trajectory *cur_traj = separatrices->evenstreamlines->trajs[i];
02360 float *curPathPoints=new float[cur_traj->nlinesegs*2];
02361 for(int j=0;j<cur_traj->nlinesegs;j++){
02362 curPathPoints[2*j]=(cur_traj->linesegs[j].start[0]-realWorld_to_field_offset_x)*realWorld_to_field_scale;
02363 curPathPoints[2*j+1]=(cur_traj->linesegs[j].start[1]-realWorld_to_field_offset_x)*realWorld_to_field_scale;
02364 }
02365 int *curPathInfoGain_cu=new int[cur_traj->nlinesegs];
02366 calPathInfoGain(pointCollection, curPathPoints, curPathInfoGain_cu,frontierPoints.data.size()/3,cur_traj->nlinesegs);
02367 std::vector<int> curPathInfoGain;
02368 float averageInfoGain=0;
02369 int maxInfoGain= 0;
02370 int minInfoGain=std::numeric_limits<int>::max();
02371 for(int k=0;k<cur_traj->nlinesegs;k++){
02372 curPathInfoGain.push_back(curPathInfoGain_cu[k]);
02373 if(maxInfoGain< curPathInfoGain_cu[k])
02374 maxInfoGain=curPathInfoGain_cu[k];
02375 if(minInfoGain>curPathInfoGain_cu[k])
02376 minInfoGain=curPathInfoGain_cu[k];
02377 averageInfoGain+=curPathInfoGain_cu[k];
02378 }
02379 averageInfoGain/=cur_traj->nlinesegs;
02380 cur_traj->infoGain=maxInfoGain;
02381 degptsPathsInfoGain.push_back(curPathInfoGain);
02382 delete curPathPoints;
02383 delete curPathInfoGain_cu;
02384 }
02385 delete pointCollection;
02386 }
02387
02388
02389 bool TfCore::check_reach_trisector(){
02390 listen_to_robot_loc();
02391 if(validDegpts.size()==0) return false;
02392 float min_dist=std::numeric_limits<float>::max();
02393 for(int i=0;i<validDegpts.size();i++){
02394 if(validDegpts[i].type == 1){
02395 float deta_x=validDegpts[i].gcx-robot_loc->pos[0];
02396 float deta_y=validDegpts[i].gcy-robot_loc->pos[1];
02397 float dist=sqrt(deta_x*deta_x+deta_y*deta_y);
02398 if(dist<min_dist){
02399 targetTrisectorIndex=i;
02400 min_dist=dist;
02401 }
02402 }
02403 }
02404 if(min_dist<TRISECTOR_REACH_THRESHOLD){
02405 return true;
02406 }else{
02407 return false;
02408 }
02409 }
02410
02411 void TfCore::ensure_robot_safety(){
02412 if(ifCancelPath) return;
02413 listen_to_robot_loc();
02414 double min_dist=std::numeric_limits<double>::max();
02415 for(int i=0;i<contours2Field.size();i++)
02416 {
02417 for (int j=0;j<contours2Field[i].size();j++)
02418 {
02419 double x_dist=robot_loc->pos[0]-contours2Field[i][j].x;
02420 double y_dist=robot_loc->pos[1]-contours2Field[i][j].y;
02421 double cur_dist=sqrt(x_dist*x_dist+y_dist*y_dist);
02422 cur_dist=cur_dist*realWorld_to_field_scale;
02423 if(min_dist>cur_dist)
02424 min_dist=cur_dist;
02425 if (cur_dist<safeDistance)
02426 {
02427 cancelPath();
02428 ifCancelPath=true;
02429 return;
02430 }
02431 }
02432 }
02433 }
02434
02435
02436 void TfCore::reset_regular_and_degenrateElem(){
02437
02438 free(ten_regularelems);
02439 ten_regularelems=NULL;
02440 if(ten_regularelems == NULL)
02441 {
02442 ten_regularelems=(TenRegularElem *)malloc(sizeof(TenRegularElem)*curMaxNumTenRegElems);
02443 if(ten_regularelems == NULL)
02444 exit(-1);
02445 }
02446 nten_regelems = 0;
02447
02448 free(ten_designelems);
02449 ten_designelems = NULL;
02450 if(ten_designelems == NULL)
02451 {
02452 ten_designelems=(Degenerate_Design *)malloc(sizeof(Degenerate_Design)*curMaxNumTenDesignElems);
02453 if(ten_designelems == NULL)
02454 exit(-1);
02455 }
02456 ntenelems = 0;
02457 }
02458
02459
02460
02461 void TfCore::locat_point_inMap(double pos[2],cv::Point2i &mapLoc){
02462
02463 double x=(pos[0]-realWorld_to_field_offset_x)*realWorld_to_field_scale;
02464 double y=(pos[1]-realWorld_to_field_offset_y)*realWorld_to_field_scale;
02465
02466 int lowerX = 0;
02467 int upperX = dirMap.info.width;
02468 do
02469 {
02470 int delim = (lowerX + upperX)/2;
02471 double tmp_x = dirMapInWorld[0][delim].x-dirMap.info.resolution*0.5;
02472
02473 if(x < tmp_x)
02474 upperX = delim;
02475 else
02476 lowerX = delim;
02477 }
02478 while(upperX - lowerX > 1);
02479 mapLoc.y=lowerX;
02480
02481
02482 int lowerY = 0;
02483 int upperY = dirMap.info.height;
02484
02485 do
02486 {
02487 int delim = (lowerY + upperY)/2;
02488 double tmp_y=dirMapInWorld[delim][0].y-dirMap.info.resolution*0.5;
02489
02490 if(y>tmp_y)
02491 upperY = delim;
02492
02493 else
02494 lowerY = delim;
02495 }
02496 while(upperY - lowerY > 1);
02497 mapLoc.x=lowerY;
02498 }
02499
02500
02501 void TfCore::filterDegpts(){
02502 if(ndegpts==0) return;
02503 validDegpts.clear();
02504 std::vector<DegeneratePt> tmp_validDegpts;
02505 for (int i=0;i<ndegpts; i++){
02506 double x=(degpts[i].gcx-realWorld_to_field_offset_x)*realWorld_to_field_scale;
02507 double y=(degpts[i].gcy-realWorld_to_field_offset_y)*realWorld_to_field_scale;
02508 if(x>=dirMapInWorld[0][dirMap.info.width-1].x-dirMap.info.resolution*0.5 || x<=dirMapInWorld[0][0].x-dirMap.info.resolution*0.5 ||
02509 y>=dirMapInWorld[0][0].y-dirMap.info.resolution*0.5 || y<=dirMapInWorld[dirMap.info.height-1][0].y-dirMap.info.resolution*0.5 ){
02510 continue;
02511 }
02512 cv::Point2i mapLoc;
02513 int region_num=8;
02514 double pos[2];
02515 pos[0]=degpts[i].gcx;
02516 pos[1]=degpts[i].gcy;
02517 locat_point_inMap(pos,mapLoc);
02518 int region_x_min,region_x_max,region_y_min,region_y_max;
02519 if(mapLoc.x-region_num>-1) region_y_min=mapLoc.x-region_num; else region_y_min=0;
02520 if(mapLoc.x+region_num<dirMap.info.height) region_y_max=mapLoc.x+region_num; else region_y_max=dirMap.info.height-1;
02521 if(mapLoc.y-region_num>-1) region_x_min=mapLoc.y-region_num; else region_x_min=0;
02522 if(mapLoc.y+region_num<dirMap.info.width) region_x_max=mapLoc.y+region_num; else region_x_max=dirMap.info.width-1;
02523 bool if_valid=true;
02524 for(int l=region_x_min;l<=region_x_max;l++)
02525 for(int m=region_y_min; m<=region_y_max; m++)
02526 {
02527 if(dirMap.data[l+dirMap.info.width*m]!=0)
02528 {
02529 if_valid=false;
02530 break;
02531 }
02532
02533 }
02534 if(if_valid)
02535 tmp_validDegpts.push_back(degpts[i]);
02536 }
02537 std::set<int> deleteIndex;
02538 if(tmp_validDegpts.size()>1){
02539 for(int i=0;i<tmp_validDegpts.size();i++){
02540 for(int j=i+1;j<tmp_validDegpts.size();j++){
02541 if(deleteIndex.find(j)!=deleteIndex.end()) continue;
02542 float deta_x=tmp_validDegpts[i].gcx-tmp_validDegpts[j].gcx;
02543 float deta_y=tmp_validDegpts[i].gcy-tmp_validDegpts[j].gcy;
02544 if(sqrt(deta_x*deta_x+deta_y*deta_y)<2*1e-2){
02545 if(fabs(tmp_validDegpts[i].type-tmp_validDegpts[j].type)!=1)continue;
02546 deleteIndex.insert(i);
02547 deleteIndex.insert(j);
02548 break;
02549 }
02550 }
02551 }
02552 }
02553 for(int i=0;i<tmp_validDegpts.size();i++){
02554 if(deleteIndex.find(i)==deleteIndex.end())
02555 validDegpts.push_back(tmp_validDegpts[i]);
02556 }
02557 for(int i=0;i<validDegpts.size();i++){
02558 validDegpts[i].valid_index=i;
02559 compute_separatrixVec_degpt_quad(i);
02560 }
02561 }
02562
02563
02564 void TfCore::display_valid_trisectors(GLenum mode)
02565 {
02566 if (validTriDegpts.size()==0) return;
02567 for(int i = 0; i < validTriDegpts.size(); i++)
02568 {
02569 glColor3f(0, 1, 0);
02570
02571 drawSolidCircle_size(validTriDegpts[i].gcx, validTriDegpts[i].gcy, 0.008/zoom_factor);
02572
02573 glColor3f(0, 0, 1);
02574 glLineWidth(1.4);
02575 draw_hollow_circle_size(validTriDegpts[i].gcx, validTriDegpts[i].gcy, 0.0085/zoom_factor);
02576 }
02577 glFlush();
02578 }
02579
02580 void TfCore::display_valid_degenerate_pts(GLenum mode)
02581 {
02582 if (validDegpts.size()==0) return;
02583 for(int i = 0; i < validDegpts.size(); i++)
02584 {
02585
02586 if(validDegpts[i].type == 0)
02587 glColor3f(1, 0, 0);
02588 else if(validDegpts[i].type == 1)
02589 glColor3f(0, 1, 0);
02590 else
02591 glColor3f(1, 1, 1);
02592
02593 drawSolidCircle_size(validDegpts[i].gcx, validDegpts[i].gcy, 0.0045/zoom_factor);
02594
02595 glColor3f(0, 0, 0);
02596 glLineWidth(1.4);
02597 draw_hollow_circle_size(validDegpts[i].gcx, validDegpts[i].gcy, 0.005/zoom_factor);
02598 }
02599 glFlush();
02600 }
02601
02602
02603
02604
02605 void TfCore::get_laplace_TVTF(int which_slice){
02606
02607 int curStep=which_slice-keyframes->keyframes[keyframes->nkeyframes-2]->keyFrameID;
02608 int cur_vertID;
02609 int variableID;
02610 for(int j=0; j<quadmesh->nverts; j++)
02611 {
02612 cur_vertID = curStep*quadmesh->nverts+j;
02613 QuadVertex *v=quadmesh->quad_verts[j];
02614 if(vertTimeList->vertsTime[cur_vertID]->isConstraint)
02615 {
02616 OneKeyFrame *thekeyframe = keyframes->get_frame_pointer(which_slice);
02617 v->Jacobian.entry[0][0] = thekeyframe->jacobian_vals[j].entry[0][0];
02618 v->Jacobian.entry[0][1] = thekeyframe->jacobian_vals[j].entry[0][1];
02619 }
02620 else
02621 {
02622 variableID=(curStep-1)*quadmesh->nverts+j;
02623 v->Jacobian.entry[0][0] = vecsTime[variableID].entry[0];
02624 v->Jacobian.entry[0][1] = vecsTime[variableID].entry[1];
02625 }
02626 double theta = atan2( v->Jacobian.entry[0][1], v->Jacobian.entry[0][0]);
02627
02628 v->major.entry[0] = cos(theta/2.);
02629 v->major.entry[1] = sin(theta/2.);
02630
02631
02632 v->minor.entry[0] = cos((theta+M_PI)/2.);
02633 v->minor.entry[1] = sin((theta+M_PI)/2.);
02634
02635 v->major_ang = atan2(v->major.entry[1],v->major.entry[0]);
02636 v->minor_ang = atan2(v->minor.entry[1], v->minor.entry[0]);
02637
02638 v->minor.entry[0]=cos(v->minor_ang);
02639 v->minor.entry[1]=sin(v->minor_ang);
02640
02641 v->tensor_major_ang = v->major_ang;
02642
02643 v->tran_vec.set(cos(2*v->tensor_major_ang), sin(2*v->tensor_major_ang));
02644
02645 double major_ang_cos = cos(v->major_ang);
02646 double major_ang_sin = sin(v->major_ang);
02647
02648 v->major_ang = major_ang_cos*major_ang_cos;
02649 if(major_ang_cos<0)
02650 v->major_cos = true;
02651 else
02652 v->major_cos = false;
02653 if(major_ang_sin<0)
02654 v->major_sin = true;
02655 else
02656 v->major_sin = false;
02657
02658 double minor_ang_cos = cos(v->minor_ang);
02659 double minor_ang_sin = sin(v->minor_ang);
02660
02661 v->minor_ang = minor_ang_cos*minor_ang_cos;
02662
02663 if(minor_ang_cos<0)
02664 v->minor_cos = true;
02665 else
02666 v->minor_cos = false;
02667 if(minor_ang_sin<0)
02668 v->minor_sin = true;
02669 else
02670 v->minor_sin = false;
02671 }
02672 }
02673
02674 void TfCore::update_cur_TF_keyframe()
02675 {
02676 if(keyframes == NULL) return;
02677
02678 if(!enRelaxKeyframeOn)
02679 {
02680 cal_TF_at_slice_keyframe_interp(curSliceID);
02681 cal_all_eigenvecs_quad();
02682 }
02683 else
02684 {
02685
02686 get_laplace_TVTF(curSliceID);
02687 normalized_tensorfield_quad();
02688 }
02689 curSliceID ++;
02690
02691 }
02692
02693 void TfCore::cal_TF_at_slice_keyframe_interp(int which_slice)
02694 {
02695
02696 int i;
02697 bool is_keyframe = false;
02698 int keyframeID1, keyframeID2;
02699 double ratio = 0;
02700
02701 keyframeID1 = keyframeID2 = -1;
02702
02703 for(i=0; i<keyframes->nkeyframes; i++)
02704 {
02705 if(which_slice < keyframes->keyframes[i]->keyFrameID)
02706 {
02707 keyframeID1 = i-1;
02708 keyframeID2 = i;
02709 ratio = (double)(which_slice-keyframes->keyframes[i-1]->keyFrameID)/
02710 (double)(keyframes->keyframes[i]->keyFrameID-keyframes->keyframes[i-1]->keyFrameID);
02711 break;
02712 }
02713 else if(which_slice == keyframes->keyframes[i]->keyFrameID)
02714 {
02715 keyframeID1 = i;
02716 is_keyframe = true;
02717 break;
02718 }
02719 }
02720
02721 if(i==keyframes->nkeyframes-1 && keyframeID1<0)
02722 keyframeID1 = keyframes->nkeyframes-1;
02723
02724
02725 if(is_keyframe)
02726 {
02727 copy_from_keyframe(keyframeID1);
02728 }
02729
02730 else
02731 {
02732 if(keyframeID2 < 0)
02733 {
02734
02735
02736 }
02737
02738 else
02739 {
02740 cal_TF_at_inbetween_slice_keyframe_interp(ratio, keyframeID1, keyframeID2);
02741 }
02742 }
02743 }
02744
02745 void TfCore::copy_from_keyframe(int keyframelistPos)
02746 {
02747 int i;
02748
02749 for(i=0; i<quadmesh->nverts; i++)
02750 {
02751 quadmesh->quad_verts[i]->Jacobian = keyframes->keyframes[keyframelistPos]->jacobian_vals[i];
02752 }
02753
02754
02755 }
02756
02757 void TfCore::cal_TF_at_inbetween_slice_keyframe_interp(double ratio, int start, int end)
02758 {
02759
02760
02761
02762 int i;
02763 icMatrix2x2 vect, vec1, vec2;
02764
02765 double ang0, ang1, ang2;
02766
02767 for(i=0; i<quadmesh->nverts; i++)
02768 {
02769 vec1 = keyframes->keyframes[start]->jacobian_vals[i];
02770 vec2 = keyframes->keyframes[end]->jacobian_vals[i];
02771
02772 if(InterpScheme == 1)
02773 {
02774 vect = vec1+ratio*(vec2-vec1);
02775 }
02776
02777 else if (InterpScheme == 2)
02778 {
02779
02780 icMatrix2x2 vec0;
02781 vec0 = keyframes->keyframes[0]->jacobian_vals[i];
02782 vec1 = keyframes->keyframes[1]->jacobian_vals[i];
02783 vec2 = keyframes->keyframes[2]->jacobian_vals[i];
02784
02785 vect = (1-ratio)*((1-ratio)*vec0+ratio*vec1)
02786 +ratio*((1-ratio)*vec1+ratio*vec2);
02787 }
02788
02789 else if (InterpScheme == 3)
02790 {
02791 icMatrix2x2 pseudo_vec1 = 0.5*(vec2-vec1);
02792 icMatrix2x2 pseudo_vec2;
02793 float s = ratio;
02794 float h1 = 2*s*s*s - 3*s*s*s + 1;
02795 float h2 = -2*s*s*s + 3*s*s;
02796 float h3 = s*s*s - 2*s*s + s;
02797 float h4 = s*s*s - s*s;
02798
02799 if (end+1 >= keyframes->nkeyframes)
02800 pseudo_vec2 = pseudo_vec1;
02801 else
02802 {
02803 pseudo_vec2 = 0.5*(keyframes->keyframes[end+1]->jacobian_vals[i]-vec2);
02804 }
02805 vect = h1*vec1 +
02806 h2*vec2 +
02807 h3*pseudo_vec1 +
02808 h4*pseudo_vec2;
02809 }
02810
02811 QuadVertex *v=quadmesh->quad_verts[i];
02812 v->Jacobian = vect;
02813 }
02814 }
02815
02816
02817 void TfCore::update_tensor_field(){
02818 update_cur_TF_keyframe();
02819 init_degpts();
02820
02821 render_alpha_map_quad();
02822 locate_degpts_cells_tranvec_quad();
02823 }
02824
02825 void TfCore::init_keyframeList(int size){
02826 if(keyframes == NULL)
02827 keyframes = new KeyFrameList(size);
02828 }
02829
02830 void TfCore::set_cur_as_keyframe(int frameID)
02831 {
02832 keyframes->save_cur_field(frameID, quadmesh);
02833 }
02834
02835 void TfCore::publish_image(){
02836 glReadBuffer(GL_BACK);
02837 glReadPixels(0, 0,NPIX,NPIX, GL_RGB, GL_UNSIGNED_BYTE, rgb_im);
02838 cv_bridge::CvImage img_ptr_rgb;
02839 img_ptr_rgb.image=cv::Mat(NPIX,NPIX, CV_8UC3);
02840 cv::Mat& mat_rgb = img_ptr_rgb.image;
02841
02842 cv::MatIterator_<cv::Vec3b> it=mat_rgb.begin<cv::Vec3b>();
02843 for (int i = NPIX-1;i >-1; i--)
02844 {
02845 for (int j = 0; j < NPIX; j++)
02846 {
02847 (*it)[2]=rgb_im[i * NPIX*3 + j*3+0]; (*it)[1]=rgb_im[i * NPIX*3 + j*3+1]; (*it)[0]=rgb_im[i * NPIX*3 + j*3+2];
02848 ++it;
02849 }
02850 }
02851 sensor_msgs::ImagePtr msg_rgb=cv_bridge::CvImage(std_msgs::Header(), "bgr8", mat_rgb).toImageMsg();
02852 int count=0;
02853 while(count<3){
02854 rgb_pub.publish(msg_rgb);
02855 count++;
02856 }
02857
02858 }
02859
02860 void TfCore::create_paraThread(){
02861 for (int i = 0; i < EXTRA_THREAD_NUM; i++)
02862 {
02863 ParaThread *myThread = new ParaThread();
02864 myThread->setID(i+1);
02865 myThread->connectTensorField(this);
02866 m_myThreads.push_back(myThread);
02867 }
02868 }
02869 void TfCore::parallel_update_tensorField(){
02870 int x1 = 0, x2 = 0;
02871 for (int i = 0; i < EXTRA_THREAD_NUM; i++)
02872 {
02873 split_tensorField(i+1, EXTRA_THREAD_NUM+1, x1, x2);
02874 m_myThreads[i]->setUpdateTensorFieldMission(x1, x2);
02875 m_myThreads[i]->start();
02876 }
02877 split_tensorField(0, EXTRA_THREAD_NUM+1, x1, x2);
02878 parallel_cal_tensorvals_quad(x1,x2);
02879 for (int i = 0; i < EXTRA_THREAD_NUM; i++)
02880 m_myThreads[i]->wait();
02881
02882 normalized_tensorfield_quad();
02883
02884 }
02885 void TfCore::split_tensorField( int i, int threadNum, int &x1, int &x2){
02886 int width = quadmesh->nverts/ threadNum;
02887 int last_remainder = quadmesh->nverts % width;
02888 x1 = i * width + (i<last_remainder%threadNum? i: last_remainder%threadNum);
02889 x2 = (i+1) * width + (i+1<last_remainder%threadNum? i+1: last_remainder%threadNum);
02890 }
02891 void TfCore::parallel_cal_tensorvals_quad(int &x1, int &x2){
02892 QuadVertex *v;
02893 double t[4]={0.};
02894 for(int i=x1; i<x2; i++)
02895 {
02896 v = quadmesh->quad_verts[i];
02897 get_tensor(v->x, v->y, t);
02898 v->Jacobian.entry[0][0] = t[0];
02899 v->Jacobian.entry[0][1] = t[1];
02900 v->Jacobian.entry[1][0] = t[2];
02901 v->Jacobian.entry[1][1] = t[3];
02902 cal_eigenvecs_onevert_quad(i);
02903 }
02904 }
02905
02906 void TfCore::Laplace_relax_timeDep(){
02907
02908 init_vertTimeList();
02909 add_verts_to_vertTimeList();
02910 set_constraints_keyframes();
02911 count_nonconstrained_verts();
02912
02913 int num_nonconstrained_verts = vertTimeList->total_notconstraint_verts;
02914
02915 if(num_nonconstrained_verts < 2)
02916 {
02917 fprintf(stderr, "Can not find enough inner vertices. \n");
02918 return;
02919 }
02920
02921 int i;
02922 Vertex *cur_v;
02923 int NMAX=10*num_nonconstrained_verts;
02924
02925 Vec_INT tempija(NMAX);
02926 Vec_DP tempsa(NMAX);
02927
02928 DP err;
02929 Vec_DP b(num_nonconstrained_verts),x(num_nonconstrained_verts);
02930
02931 Mat_DP bound_vert(0.0, num_nonconstrained_verts, 2);
02932
02933 const int ITOL=1,ITMAX=500;
02934 const DP TOL=ERROR_LAPLACE;
02935 int iter;
02936
02937 con_linear_Sys_spatioTemp(tempsa, tempija, bound_vert);
02938
02939 Vec_INT ija(tempija[num_nonconstrained_verts]);
02940 Vec_DP sa(tempija[num_nonconstrained_verts]);
02941
02942 for(i = 0; i < tempija[num_nonconstrained_verts]; i++)
02943 {
02944 ija[i] = tempija[i];
02945 sa[i] = tempsa[i];
02946 }
02947
02948 ija_p = &ija;
02949 sa_p = &sa;
02950
02951
02952 vecsTime=new icVector2[num_nonconstrained_verts];
02953
02954
02956 for (i = 0; i < vertTimeList->total_notconstraint_verts; i++)
02957 {
02958 x[i]=0.0;
02959 b[i]= bound_vert[i][0];
02960 }
02961 linbcg(b,x,ija_p,sa_p,ITOL,TOL,ITMAX,iter,err);
02962
02964 for (i = 0; i < num_nonconstrained_verts; i++)
02965 {
02966 vecsTime[i].entry[0] = x[i];
02967 }
02968
02970 for (i = 0; i < vertTimeList->total_notconstraint_verts; i++)
02971 {
02972 x[i]=0.0;
02973 b[i]= bound_vert[i][1];
02974 }
02975 linbcg(b,x,ija_p,sa_p,ITOL,TOL,ITMAX,iter,err);
02976
02978 for (i = 0; i < num_nonconstrained_verts; i++)
02979 {
02980 vecsTime[i].entry[1] = x[i];
02981 }
02982 }
02983
02984 void TfCore::init_vertTimeList(){
02985 if(vertTimeList != NULL){
02986 delete vertTimeList;
02987 vertTimeList=NULL;
02988 if(vecsTime!= NULL){
02989 delete vecsTime;
02990 vecsTime=NULL;
02991 }
02992 }
02993 vertTimeList = new VertTimeList(quadmesh->nverts,quadmesh->nverts*(interFrameNum+1));
02994 }
02995 void TfCore::add_verts_to_vertTimeList(){
02996 int i, j;
02997
02998 if(vertTimeList == NULL)
02999 init_vertTimeList();
03000
03001 for(i=0; i<interFrameNum+1; i++)
03002 {
03003 for(j=0; j<quadmesh->nverts; j++)
03004 vertTimeList->add_new(i, j);
03005 }
03006 }
03007 void TfCore::set_constraints_keyframes(){
03008 int i, j;
03009 int cur_step;
03010 for(i=0; i<2;i++){
03011 if (i==0)
03012 cur_step=0;
03013 else
03014 cur_step=interFrameNum;
03015 for(j=0; j<quadmesh->nverts; j++)
03016 vertTimeList->set_constraint_at_vert(cur_step,j);
03017 }
03018 }
03019 void TfCore::count_nonconstrained_verts(){
03020 int i;
03021 vertTimeList->total_notconstraint_verts = 0;
03022 for(i=0; i<vertTimeList->nvertsTime; i++)
03023 {
03024 if(!vertTimeList->vertsTime[i]->isConstraint)
03025 {
03026
03027 vertTimeList->vertsTime[i]->variableID = vertTimeList->total_notconstraint_verts;
03028
03029 vertTimeList->total_notconstraint_verts ++;
03030 }
03031 }
03032 }
03033
03034 void TfCore::con_linear_Sys_spatioTemp(Vec_DP &tsa, Vec_INT &tija, Mat_DP &bound_v){
03035 if(vertTimeList == NULL) return;
03036
03037 int i, j;
03038 QuadVertex *adj_v, *cur_v = NULL;
03039 QuadEdge *adj_e;
03040 int *RegionIndex;
03041 int num_nonzeroarow = 0;
03042 int num_elements = 0;
03043 int cur_variableID = 0;
03044 unsigned char type = -1;
03045 double time_axis_weight = 30;
03046
03047
03048 for(i = 0; i < vertTimeList->total_notconstraint_verts; i++)
03049 tsa[i] = 1. + time_axis_weight*2.;
03050
03051 num_elements = vertTimeList->total_notconstraint_verts+1;
03052
03053
03054
03055 for(i = 0; i < quadmesh->nverts*(interFrameNum+1); i++)
03056 {
03057 if(vertTimeList->vertsTime[i]->isConstraint)
03058 continue;
03059
03060 cur_variableID = vertTimeList->vertsTime[i]->variableID;
03061 cur_v = quadmesh->quad_verts[vertTimeList->vertsTime[i]->which_vert];
03062 RegionIndex = new int[cur_v->Num_edge+2];
03063
03064 int cur_time = vertTimeList->vertsTime[i]->time_step;
03065
03066 num_nonzeroarow = 0;
03067
03068 type = -1;
03069
03070 for(j = 0; j < cur_v->Num_edge; j++)
03071 {
03072 adj_e = cur_v->edges[j];
03073
03075 if( quadmesh->quad_verts[adj_e->verts[0]] != cur_v)
03076 adj_v = quadmesh->quad_verts[adj_e->verts[0]];
03077 else
03078 adj_v = quadmesh->quad_verts[adj_e->verts[1]];
03079
03080 if(vertTimeList->vertsTime[cur_time*quadmesh->nverts+adj_v->index]->isConstraint)
03081 {
03082 RegionIndex[j] = -1;
03083
03084 OneKeyFrame *thekeyframe = keyframes->get_frame_pointer(cur_time+keyframes->keyframes[keyframes->nkeyframes-2]->keyFrameID);
03085
03086
03087 if(thekeyframe != NULL)
03088 {
03089 bound_v[cur_variableID][0] += (1./cur_v->Num_edge)*thekeyframe->jacobian_vals[adj_v->index].entry[0][0];
03090 bound_v[cur_variableID][1] += (1./cur_v->Num_edge)*thekeyframe->jacobian_vals[adj_v->index].entry[0][1];
03091 }
03092 }
03093 else
03094 {
03095 RegionIndex[j] = vertTimeList->vertsTime[cur_time*quadmesh->nverts+adj_v->index]->variableID;
03096 num_nonzeroarow++;
03097 }
03098 }
03099
03100
03101 if(cur_time == 0)
03102 {
03103 RegionIndex[cur_v->Num_edge] = -1;
03104
03105 if(vertTimeList->vertsTime[i+quadmesh->nverts]->isConstraint)
03106 {
03107 RegionIndex[cur_v->Num_edge+1] = -1;
03108 OneKeyFrame *thekeyframe = keyframes->get_frame_pointer(cur_time+1+keyframes->keyframes[keyframes->nkeyframes-2]->keyFrameID);
03109 bound_v[cur_variableID][0] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][0];
03110 bound_v[cur_variableID][1] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][1];
03111 }
03112 else
03113 {
03114 RegionIndex[cur_v->Num_edge+1] = vertTimeList->vertsTime[i+quadmesh->nverts]->variableID;
03115 num_nonzeroarow++;
03116 type = 0;
03117 }
03118 }
03119 else if(cur_time == interFrameNum+1-1)
03120 {
03121 RegionIndex[cur_v->Num_edge+1] = -1;
03122
03123 if(vertTimeList->vertsTime[i-quadmesh->nverts]->isConstraint)
03124 {
03125 RegionIndex[cur_v->Num_edge] = -1;
03126 OneKeyFrame *thekeyframe = keyframes->get_frame_pointer(cur_time-1+keyframes->keyframes[keyframes->nkeyframes-2]->keyFrameID);
03127 bound_v[cur_variableID][0] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][0];
03128 bound_v[cur_variableID][1] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][1];
03129 }
03130 else
03131 {
03132 RegionIndex[cur_v->Num_edge] = vertTimeList->vertsTime[i-quadmesh->nverts]->variableID;
03133 num_nonzeroarow++;
03134 type = 1;
03135 }
03136 }
03137 else
03138 {
03139
03140 if(vertTimeList->vertsTime[i-quadmesh->nverts]->isConstraint)
03141 {
03142 RegionIndex[cur_v->Num_edge] = -1;
03143 OneKeyFrame *thekeyframe = keyframes->get_frame_pointer(cur_time-1+keyframes->keyframes[keyframes->nkeyframes-2]->keyFrameID);
03144 bound_v[cur_variableID][0] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][0];
03145 bound_v[cur_variableID][1] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][1];
03146 }
03147 else
03148 {
03149 RegionIndex[cur_v->Num_edge] = vertTimeList->vertsTime[i-quadmesh->nverts]->variableID;
03150 num_nonzeroarow++;
03151 type = 0;
03152 }
03153
03154 if(vertTimeList->vertsTime[i+quadmesh->nverts]->isConstraint)
03155 {
03156 RegionIndex[cur_v->Num_edge+1] = -1;
03157 OneKeyFrame *thekeyframe = keyframes->get_frame_pointer(cur_time+1+keyframes->keyframes[keyframes->nkeyframes-2]->keyFrameID);
03158 bound_v[cur_variableID][0] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][0];
03159 bound_v[cur_variableID][1] += time_axis_weight*thekeyframe->jacobian_vals[cur_v->index].entry[0][1];
03160 }
03161 else
03162 {
03163 RegionIndex[cur_v->Num_edge+1] = vertTimeList->vertsTime[i+quadmesh->nverts]->variableID;
03164 num_nonzeroarow++;
03165
03166 if(type == 0)
03167 type = 2;
03168 else
03169 type = 1;
03170 }
03171 }
03172
03174 BubbleSorting(RegionIndex, cur_v->Num_edge+2);
03175
03177 if(num_nonzeroarow < cur_v->Num_edge+2)
03178 {
03179 int firstnonfuyielement = cur_v->Num_edge+2 - num_nonzeroarow;
03180
03181 for(j = 0; j < num_nonzeroarow; j++)
03182 {
03183 RegionIndex[j] = RegionIndex[firstnonfuyielement + j];
03184 }
03185 }
03186
03188 tija[cur_variableID] = num_elements;
03189 for(j = 0; j < num_nonzeroarow; j++)
03190 {
03191 if(type < 0)
03192 tsa[num_elements + j] = -1./cur_v->Num_edge;
03193 else if(type == 0)
03194 {
03195 if(j == 0)
03196 tsa[num_elements+j] = -time_axis_weight;
03197 else
03198 tsa[num_elements+j] = -1./cur_v->Num_edge;
03199 }
03200 else if(type == 1)
03201 {
03202 if(j == num_nonzeroarow - 1)
03203 tsa[num_elements+j] = -time_axis_weight;
03204 else
03205 tsa[num_elements+j] = -1./cur_v->Num_edge;
03206 }
03207 else if(type == 2)
03208 {
03209 if(j == 0 || j == num_nonzeroarow - 1)
03210 tsa[num_elements+j] = -time_axis_weight;
03211 else
03212 tsa[num_elements+j] = -1./cur_v->Num_edge;
03213 }
03214
03215
03216 tija[num_elements + j] = RegionIndex[j];
03217 }
03218
03219 num_elements += num_nonzeroarow;
03220
03221 delete [] RegionIndex;
03222 }
03223
03224 tsa[vertTimeList->total_notconstraint_verts] = 0.;
03225 tija[vertTimeList->total_notconstraint_verts] = num_elements-1;
03226 }
03227
03228 void TfCore::display_bresenham_line(){
03229 if(bresenham_line_points.size()<2) return;
03230 glColor3f(0,0,1);
03231 for(int i=0;i<bresenham_line_points.size()-1;i++){
03232 glBegin(GL_LINES);
03233 double point1_x=(dirMap.info.resolution*(bresenham_line_points[i].y+0.5)+dirMap.info.origin.position.x)/realWorld_to_field_scale+realWorld_to_field_offset_x;
03234 double point1_y=(dirMap.info.resolution*(dirMap.info.height-1-bresenham_line_points[i].x+0.5)+dirMap.info.origin.position.y)/realWorld_to_field_scale+realWorld_to_field_offset_y;
03235 double point2_x=(dirMap.info.resolution*(bresenham_line_points[i+1].y+0.5)+dirMap.info.origin.position.x)/realWorld_to_field_scale+realWorld_to_field_offset_x;
03236 double point2_y=(dirMap.info.resolution*(dirMap.info.height-1-bresenham_line_points[i+1].x+0.5)+dirMap.info.origin.position.y)/realWorld_to_field_scale+realWorld_to_field_offset_y;
03237 glVertex2f(point1_x,point1_y);
03238 glVertex2f(point2_x,point2_y);
03239 glEnd();
03240 }
03241
03242 }
03243 bool TfCore::check_line_insect_obstacle(){
03244 for(int i=0; i<bresenham_line_points.size();i++){
03245 int region_num=5;
03246 int region_x_min,region_x_max,region_y_min,region_y_max;
03247 if(bresenham_line_points[i].x-region_num>-1) region_y_min=bresenham_line_points[i].x-region_num; else region_y_min=0;
03248 if(bresenham_line_points[i].x+region_num<dirMap.info.height) region_y_max=bresenham_line_points[i].x+region_num; else region_y_max=dirMap.info.height-1;
03249 if(bresenham_line_points[i].y-region_num>-1) region_x_min=bresenham_line_points[i].y-region_num; else region_x_min=0;
03250 if(bresenham_line_points[i].y+region_num<dirMap.info.width) region_x_max=bresenham_line_points[i].y+region_num; else region_x_max=dirMap.info.width-1;
03251 for(int l=region_x_min;l<=region_x_max;l++)
03252 for(int m=region_y_min; m<=region_y_max; m++)
03253 {
03254 if(dirMap.data[l+dirMap.info.width*m]!=0)
03255 return true;
03256 }
03257 }
03258
03259 return false;
03260 }
03261
03262 bool TfCore::insertLinks(int i, int j){
03263 pair<int,int> tmp_pair;
03264 set<pair<int,int>>::iterator tmp_iter;
03265 if(i<j){
03266 tmp_pair=make_pair(i,j);
03267 if(degptsLinks.find(tmp_pair)==degptsLinks.end())
03268 {
03269 degptsLinks.insert(tmp_pair);
03270 return true;
03271 }else
03272 return false;
03273
03274 }else{
03275 tmp_pair=make_pair(j,i);
03276 if(degptsLinks.find(tmp_pair)==degptsLinks.end()){
03277 degptsLinks.insert(tmp_pair);
03278 return true;
03279 }else
03280 return false;
03281 }
03282 }
03283
03284 std::map<pair<int ,int>,float> TfCore::search_degpts_mst(std::set<int> connect_degpts,int target_tri_index){
03285 std::map<pair<int ,int>,float> cur_mst;
03286 if(connect_degpts.size()==1) return cur_mst;
03287 degptsLinks.clear();
03288 int num_seps=separatrices->evenstreamlines->ntrajs;
03289 std::map<pair<int,int>,float> linkValues;
03290 for(int i=0;i<num_seps;i++){
03291 Trajectory *cur_traj=separatrices->evenstreamlines->trajs[i];
03292 int degpt_id=cur_traj->degpt_id;
03293 int linked_degpt_id=cur_traj->linked_degpt_id;
03294 pair<int,int> tmp_pair;
03295 if(degpt_id==target_tri_index && connect_degpts.find(linked_degpt_id)!=connect_degpts.end()){
03296 if(degpt_id<linked_degpt_id){
03297 if(insertLinks(degpt_id,linked_degpt_id)){
03298 tmp_pair=make_pair(degpt_id,linked_degpt_id);
03299 linkValues.insert(pair<pair<int,int>,float>(tmp_pair,cur_traj->infoGain));
03300 }
03301 }else{
03302 if(insertLinks(linked_degpt_id,degpt_id)){
03303 tmp_pair=make_pair(linked_degpt_id,degpt_id);
03304 linkValues.insert(pair<pair<int,int>,float>(tmp_pair,cur_traj->infoGain));
03305 }
03306 }
03307 }
03308 }
03309
03310 for(int i=0;i<num_seps;i++){
03311 Trajectory *cur_traj=separatrices->evenstreamlines->trajs[i];
03312 int degpt_id=cur_traj->degpt_id;
03313 if(degpt_id==target_tri_index) continue;
03314 int linked_degpt_id=cur_traj->linked_degpt_id;
03315 pair<int,int> tmp_pair;
03316 if(connect_degpts.find(degpt_id)!=connect_degpts.end() && connect_degpts.find(linked_degpt_id)!=connect_degpts.end()){
03317 if(degpt_id<linked_degpt_id){
03318 if(insertLinks(degpt_id,linked_degpt_id)){
03319 tmp_pair=make_pair(degpt_id,linked_degpt_id);
03320 linkValues.insert(pair<pair<int,int>,float>(tmp_pair,cur_traj->infoGain));
03321 }
03322 }else{
03323 if(insertLinks(linked_degpt_id,degpt_id)){
03324 tmp_pair=make_pair(linked_degpt_id,degpt_id);
03325 linkValues.insert(pair<pair<int,int>,float>(tmp_pair,cur_traj->infoGain));
03326 }
03327 }
03328
03329 }
03330 }
03331 graph g_graph(connect_degpts.size());
03332 std::map<int,int> connect_degpts_index_map_forward;
03333 std::map<int,int> connect_degpts_index_map_backward;
03334 std::set<int>::iterator iter_set;
03335 int count=0;
03336 for(iter_set=connect_degpts.begin();iter_set!=connect_degpts.end();iter_set++){
03337 connect_degpts_index_map_forward.insert(pair<int,int>(*iter_set,count));
03338 connect_degpts_index_map_backward.insert(pair<int,int>(count,*iter_set));
03339 count++;
03340 }
03341 std::map<pair<int,int>,float>::iterator iter;
03342 for(iter=linkValues.begin();iter!=linkValues.end();iter++){
03343 g_graph.addEdge(connect_degpts_index_map_forward[(*iter).first.first],connect_degpts_index_map_forward[(*iter).first.second],(*iter).second);
03344 g_graph.addEdge(connect_degpts_index_map_forward[(*iter).first.second],connect_degpts_index_map_forward[(*iter).first.first],(*iter).second);
03345 }
03346
03347 MSTStrategy *s_mst =new PrimeMST();
03348 std::vector<graph::Vertex> parent=s_mst->mst(g_graph);
03349 delete s_mst;
03350
03351 for(int i=1;i<g_graph.vertexCount();i++){
03352 int link1=connect_degpts_index_map_backward[i];
03353 int link2=connect_degpts_index_map_backward[parent[i]];
03354 pair<int,int> tmp_pair;
03355 if(link1<link2)
03356 {
03357 tmp_pair=make_pair(link1,link2);
03358 cur_mst.insert(pair<pair<int,int>,float>(tmp_pair,g_graph[i][parent[i]]));
03359 }
03360 else
03361 {
03362 tmp_pair=make_pair(link2,link1);
03363 cur_mst.insert(pair<pair<int,int>,float>(tmp_pair,g_graph[i][parent[i]]));
03364 }
03365 }
03366 return cur_mst;
03367
03368
03369 }
03370
03371 std::set<int> TfCore::find_connect_degpts(int target_tri_index){
03372 std::set<int> connect_degpts;
03373 connect_degpts.insert(target_tri_index);
03374 int num_seps=separatrices->evenstreamlines->ntrajs;
03375 for(int i=0;i<num_seps;i++){
03376 Trajectory *cur_traj=separatrices->evenstreamlines->trajs[i];
03377 if(cur_traj->linked_degpt_id=-1) continue;
03378 if(cur_traj->degpt_id==target_tri_index)
03379 {
03380 if(connect_degpts.find(cur_traj->linked_degpt_id)==connect_degpts.end())
03381 connect_degpts.insert(cur_traj->linked_degpt_id);
03382 }
03383 }
03384 if(connect_degpts.size()==1) return connect_degpts;
03385
03386 while(true){
03387 int cur_connect_degpts_num=connect_degpts.size();
03388 for(int i=0;i<num_seps;i++){
03389 Trajectory *cur_traj=separatrices->evenstreamlines->trajs[i];
03390 if(cur_traj->linked_degpt_id==-1) continue;
03391 if(connect_degpts.find(cur_traj->degpt_id)!=connect_degpts.end()){
03392 if(connect_degpts.find(cur_traj->linked_degpt_id)==connect_degpts.end())
03393 {
03394 connect_degpts.insert(cur_traj->linked_degpt_id);
03395 break;
03396 }
03397 }
03398 if(connect_degpts.find(cur_traj->linked_degpt_id)!=connect_degpts.end()){
03399 if(connect_degpts.find(cur_traj->degpt_id)==connect_degpts.end()){
03400 connect_degpts.insert(cur_traj->degpt_id);
03401 break;
03402 }
03403 }
03404 }
03405 if(connect_degpts.size()==cur_connect_degpts_num)
03406 break;
03407 }
03408 return connect_degpts;
03409 }
03410
03411
03412 Trajectory * TfCore::select_a_branch(std::map<pair<int,int>,float> cur_mst, int target_tri_index){
03413 std::vector<Trajectory *> cur_trajs;
03414 std::vector<Trajectory *> tmp_cur_trajs;
03415 std::vector<float> info_gains;
03416 int num_seps=separatrices->evenstreamlines->ntrajs;
03417 bool reach_unkown=false;
03418 for(int i=0;i<num_seps;i++){
03419 Trajectory *cur_traj=separatrices->evenstreamlines->trajs[i];
03420 if(cur_traj->degpt_id==target_tri_index)
03421 {
03422 tmp_cur_trajs.push_back(cur_traj);
03423 if(cur_traj->is_reach_unknown) reach_unkown=true;
03424 }
03425 }
03426 if(reach_unkown){
03427 for(int i=0;i<tmp_cur_trajs.size();i++){
03428 if(tmp_cur_trajs[i]->is_reach_unknown)
03429 {
03430 cur_trajs.push_back(tmp_cur_trajs[i]);
03431 info_gains.push_back(1.0/tmp_cur_trajs[i]->get_length());
03432 }
03433
03434 }
03435 }else{
03436 for(int i=0;i<tmp_cur_trajs.size();i++)
03437 cur_trajs.push_back(tmp_cur_trajs[i]);
03438 if(cur_mst.size()==0){
03439 for(int i=0;i<cur_trajs.size();i++){
03440 info_gains.push_back(cur_trajs[i]->infoGain);
03441 }
03442 }else{
03443 for(int i=0;i<cur_trajs.size();i++){
03444 if(cur_trajs[i]->linked_degpt_id==-1)
03445 {
03446 info_gains.push_back(cur_trajs[i]->infoGain);
03447 }
03448 else
03449 {
03450
03451 bool flag=false;
03452 std::map<pair<int,int>,float>::iterator iter;
03453 for(iter=cur_mst.begin();iter!=cur_mst.end();iter++)
03454 {
03455 if(((*iter).first.first==target_tri_index && (*iter).first.second==cur_trajs[i]->linked_degpt_id) || ((*iter).first.second==target_tri_index && (*iter).first.first==cur_trajs[i]->linked_degpt_id))
03456 flag=true;
03457 }
03458 if(!flag){
03459 info_gains.push_back(cur_trajs[i]->infoGain);
03460 }else{
03461 float cur_infoGain=cur_trajs[i]->infoGain;
03462 int cur_count=1;
03463 std::set<int> cur_tri_link_set;
03464 cur_tri_link_set.insert(cur_trajs[i]->linked_degpt_id);
03465 for(iter=cur_mst.begin();iter!=cur_mst.end();iter++){
03466 if((*iter).first.first==cur_trajs[i]->linked_degpt_id && (*iter).first.second!=target_tri_index)
03467 cur_tri_link_set.insert((*iter).first.second);
03468 if((*iter).first.second==cur_trajs[i]->linked_degpt_id && (*iter).first.first!=target_tri_index)
03469 cur_tri_link_set.insert((*iter).first.first);
03470 }
03471 std::set<int>::iterator iter_link=cur_tri_link_set.find(cur_trajs[i]->linked_degpt_id);
03472 cur_tri_link_set.erase(iter_link);
03473
03474 while(true){
03475 int cur_size=cur_tri_link_set.size();
03476 for(iter=cur_mst.begin();iter!=cur_mst.end();iter++){
03477 int first=(*iter).first.first;
03478 int second=(*iter).first.second;
03479 if(cur_tri_link_set.find(first)!=cur_tri_link_set.end() && cur_tri_link_set.find(second)==cur_tri_link_set.end())
03480 {
03481 cur_tri_link_set.insert(second);
03482 break;
03483 }
03484 if(cur_tri_link_set.find(second)!=cur_tri_link_set.end() && cur_tri_link_set.find(first)==cur_tri_link_set.end())
03485 {
03486 cur_tri_link_set.insert(first);
03487 break;
03488 }
03489 }
03490 if(cur_size==cur_tri_link_set.size()) break;
03491 }
03492 iter_link=cur_tri_link_set.find(cur_trajs[i]->linked_degpt_id);
03493 cur_tri_link_set.erase(iter_link);
03494 for(iter=cur_mst.begin();iter!=cur_mst.end();iter++){
03495 int first=(*iter).first.first;
03496 int second=(*iter).first.second;
03497 if(cur_tri_link_set.find(first)!=cur_tri_link_set.end() || cur_tri_link_set.find(second)!=cur_tri_link_set.end())
03498 {
03499 if(cur_infoGain<(*iter).second){
03500 cur_infoGain=(*iter).second;
03501 }
03502
03503 cur_count++;
03504 }
03505 }
03506 info_gains.push_back(cur_infoGain);
03507 }
03508 }
03509 }
03510 }
03511
03512 }
03513
03514
03515 auto biggest = std::max_element(std::begin(info_gains), std::end(info_gains));
03516 int target_branch=std::distance(std::begin(info_gains), biggest);
03517 return cur_trajs[target_branch];
03518 }
03519
03520 void TfCore::select_target_trisector_branch_move(){
03521 std::set<int> connect_degpts=find_connect_degpts(selected_target_tri);
03522 std::map<pair<int ,int>,float> cur_mst=search_degpts_mst(connect_degpts,selected_target_tri);
03523 Trajectory *target_branch=select_a_branch(cur_mst,selected_target_tri);
03524 add_separatrix_points_toRobot(target_branch);
03525 }
03526
03527 bool TfCore::check_reach_wedge(){
03528 if(major_path==NULL || major_path->evenstreamlines->ntrajs==0) return false;
03529 Trajectory *cur_traj= major_path->evenstreamlines->trajs[0];
03530 int index=cur_traj->nlinesegs-1;
03531 double loc_x=cur_traj->linesegs[index].gend[0];
03532 double loc_y=cur_traj->linesegs[index].gend[1];
03533 if(validDegpts.size()==0) return false;
03534 float min_dist=std::numeric_limits<float>::max();
03535 for(int i=0;i<validDegpts.size();i++){
03536 if(validDegpts[i].type == 0){
03537 float deta_x=validDegpts[i].gcx-loc_x;
03538 float deta_y=validDegpts[i].gcy-loc_y;
03539 float dist=sqrt(deta_x*deta_x+deta_y*deta_y);
03540 if(dist<min_dist){
03541 min_dist=dist;
03542 }
03543 }
03544 }
03545 if(min_dist<0.01){
03546 return true;
03547 }else{
03548 return false;
03549 }
03550 }