void ARController::Draw(Mat * rgbaImage) { if (drawingLevel == 2 || drawingLevel == 3) { struct timespec start,end; SET_TIME(&start); //Draw objects onto camera texture for (int i=0; i<drawObjects.size(); i++) { if (drawObjects.at(i)->IsVisible()) { LOGV(LOGTAG_ARCONTROLLER,"Drawing object %d",i); drawObjects.at(i)->Draw(rgbaImage); } } SET_TIME(&end); LOG_TIME_PRECISE("ARController Drawing",start,end); } //resetButton->Draw(rgbaImage); certaintyIndicator->Draw(rgbaImage); //Draw FPS label on top of everything else fpsLabel->Draw(rgbaImage); //Update textured quad quadBackground->SetImage(rgbaImage); }
static void event_init(ACL_EVENT *eventp, int fdsize, int delay_sec, int delay_usec) { eventp->fdsize = fdsize; /* eventp->fdtab_free_cnt = 0; */ eventp->fdcnt = 0; eventp->fdcnt_ready = 0; eventp->fdtabs = (ACL_EVENT_FDTABLE **) acl_mycalloc(fdsize,sizeof(ACL_EVENT_FDTABLE *)); eventp->fdtabs_ready = (ACL_EVENT_FDTABLE **) acl_mycalloc(fdsize, sizeof(ACL_EVENT_FDTABLE *)); eventp->maxfd = 0; eventp->nested = 0; eventp->delay_sec = delay_sec + delay_usec / 1000000; eventp->delay_usec = delay_usec % 1000000; acl_ring_init(&eventp->timer_head); eventp->timer_keep = 0; SET_TIME(eventp->present); SET_TIME(eventp->last_debug); eventp->check_inter = 100000; /* default: 100 ms */ if (eventp->init_fn) eventp->init_fn(eventp); }
void ARController::getImages(Engine * engine) { struct timespec start, end; //Retrieve image from the camera if (debugUI->currentDrawMode == DrawModes::ColorImage) { SET_TIME(&start); engine->imageCollector->newFrame(); engine->imageCollector->getColorCameraImage(*rgbImage); SET_TIME(&end); LOG_TIME_PRECISE("Color Image Capture", start, end); cvtColor(*rgbImage, *grayImage, CV_RGBA2GRAY, 1); } else { SET_TIME(&start); engine->imageCollector->newFrame(); engine->imageCollector->getGrayCameraImage(*grayImage); SET_TIME(&end); LOG_TIME_PRECISE("Gray Image Capture", start, end); cvtColor(*grayImage, *rgbImage, CV_GRAY2RGBA, 4); } }
void get_cpu_time (Time* usrT, Time* sysT) { // // Get the user and/or system cpu times in a system independent way. time_struct_t ts; GET_TIME(ts); if (usrT != NULL) { SET_TIME(usrT, USR_TIME(ts)); if (usrT->seconds < lastU.seconds) usrT->seconds = lastU.seconds; if ((usrT->seconds == lastU.seconds) && (usrT->uSeconds < lastU.uSeconds)) usrT->uSeconds = lastU.uSeconds; lastU = *usrT; } if (sysT != NULL) { SET_TIME(sysT, SYS_TIME(ts)); if (sysT->seconds < lastS.seconds) sysT->seconds = lastS.seconds; if ((sysT->seconds == lastS.seconds) && (sysT->uSeconds < lastS.uSeconds)) sysT->uSeconds = lastS.uSeconds; lastS = *sysT; } }
//Finds vertical edges and stores in edgeArray static void FindEdgesVertical(const Mat & inputImg, Mat & edgeArray, int xPosition, short threshold, bool nonMaxSuppress, int detectorSize) { //const short detectorSize = 3; const short maxColumn = inputImg.rows - detectorSize; struct timespec start,end; SET_TIME(&start); //Copy the column into a row for faster access Mat rowBasedImg(1,inputImg.rows,CV_8U); for (int i=0;i<inputImg.rows;i++) { rowBasedImg.at<unsigned char>(0,i) = inputImg.at<unsigned char>(i,xPosition); } const unsigned char * imgRowPtr = rowBasedImg.ptr<unsigned char>(0); Mat tmpEdgeArray = Mat::zeros(1,inputImg.rows,CV_16S); //Located and scored edges short * edgeRowPtr = tmpEdgeArray.ptr<short>(0); edgeArray = Mat::zeros(1,inputImg.rows,CV_16S); short * outputEdgeRowPtr = edgeArray.ptr<short>(0); for (int j=detectorSize;j < maxColumn;j++) { if (detectorSize == 3) edgeRowPtr[j] = -((short)(imgRowPtr[j+1] + (short)imgRowPtr[j+2] + (short)imgRowPtr[j+3])) + (short)imgRowPtr[j-1] + (short)imgRowPtr[j-2] + (short)imgRowPtr[j-3]; else if (detectorSize == 4) edgeRowPtr[j] = -((short)imgRowPtr[j+1] + (short)imgRowPtr[j+2] + (short)imgRowPtr[j+3] + (short)imgRowPtr[j+4]) + (short)imgRowPtr[j-1] + (short)imgRowPtr[j-2] + (short)imgRowPtr[j-3] + (short)imgRowPtr[j-4]; else edgeRowPtr[j] = -((short)imgRowPtr[j+1] + (short)imgRowPtr[j+2]) + (short)imgRowPtr[j-1] + (short)imgRowPtr[j-2]; if (j > (detectorSize + 1) && edgeRowPtr[j-1] != 0 && abs(edgeRowPtr[j-1]) > threshold && ( !nonMaxSuppress || ( abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j-2]) && // || (abs(edgeRowPtr[j-1]) == abs(edgeRowPtr[j-2]) && abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j-3]))) && abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j]) ) ) ) { outputEdgeRowPtr[j-1] = (edgeRowPtr[j-1] < 0) ? 1 : -1; } /*else { outputEdgeRowPtr[j-1] = 0; }*/ } SET_TIME(&end); LOG_TIME_PRECISE("VerticalEdgeTest",start,end); }
AugmentedView::AugmentedView(UIElementCollection * window, Engine * engine, cv::Mat _cameraMatrix) { cameraMatrix = new Mat(); _cameraMatrix.copyTo(*cameraMatrix); rotation = new Mat(); position = new Mat(); objectVector = std::vector<ARObject*>(); LOGI(LOGTAG_POSITION, "Created AugmentedView"); canDraw = false; Scalar selectColor = Colors::DodgerBlue; selectColor[3] = 80; selectionIndicator = new ARObject(OpenGLHelper::CreateSolidColorCube(1,selectColor)); selectedObject = NULL; SET_TIME(&lastSelectionTime); testObject = new ARObject(OpenGLHelper::CreateSolidColorCube(10,Colors::OrangeRed)); tabs = new TabDisplay(true); window->AddChild(tabs); createNext =false; GridLayout * myGrid = new GridLayout(cv::Size2i(5,4)); cancelSelection = new Button("Cancel"); cancelSelection->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this)); myGrid->AddChild(cancelSelection,Point2i(4,3)); cancelSelection->SetVisible(false); cancelSelection->Name = "Cancel"; releaseSelection = new Button("Release"); releaseSelection->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this)); myGrid->AddChild(releaseSelection,Point2i(4,2)); releaseSelection->SetVisible(false); releaseSelection->Name = "Release"; Button * createCube = new Button("Create"); createCube->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this)); myGrid->AddChild(createCube,Point2i(4,1)); createCube->Name = "Create"; createCube->FillColor = Colors::LightGreen; Button * deleteObject = new Button("Delete"); deleteObject->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this)); myGrid->AddChild(deleteObject,Point2i(4,0)); deleteObject->Name = "Delete"; deleteObject->FillColor = Colors::Orange; tabs->AddTab("AR",myGrid); LOGD(LOGTAG_ARINPUT,"Laying out tabs %d,%d",engine->imageWidth,engine->imageHeight); tabs->DoLayout(Rect(0,0,engine->imageWidth,engine->imageHeight)); tabs->SetTab(0); }
void QuadBackground::Render(OpenGL * openGL) { struct timespec start,end; SET_TIME(&start); OpenGLSettings(); //Draw object SetMatrices(openGL); //glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID); glUniform1i(openGL->renderData.textureLocation,0); //Debugging - Draw a solid color to texture if (ENABLE_TEXTURE_COLOR) { u_int32_t * pxData = new u_int32_t[textureWidth*textureHeight]; for (int i=0;i<(textureWidth*textureHeight);i++) { pxData[i] = 123912048; } glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, pxData); delete[] pxData; } //Update the texture glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,imageWidth,imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, imagePixels); openGL->DrawGLObject(testCube); openGL->DrawGLObject(texturedQuad); ResetGLSettings(); SET_TIME(&end); LOG_TIME("QuadBG Render", start, end); }
/****************************************************************************** * The interrupt service routine */ __irq void EXTI15_10_IRQHandler(void){ uint8_t lwmode = wmode; //let this variables in registers uint8_t lmode = mode; if((lwmode == OWW_WRITE_0)) {SET_LOW;lwmode = OWW_NO_WRITE;} //if necessary set 0-Bit DIS_OWINT; //disable interrupt, only in OWM_SLEEP mode it is active switch(lmode){ case OWM_SLEEP: SET_TIME(OWT_MIN_RESET); EN_OWINT; //other edges ? break; //Start of reading with falling edge from master, reading closed in timer isr case OWM_MATCH_ROM: //falling edge wait for receive case OWM_WRITE_SCRATCHPAD: case OWM_READ_COMMAND: SET_TIME(OWT_READLINE); //wait a time for reading break; case OWM_SEARCH_ROM: //Search algorithm waiting for receive or send if (srcount<2) { //this means bit or complement is writing, SET_TIME(OWT_LOWTIME); } else SET_TIME(OWT_READLINE); //init for read answer of master break; case OWM_READ_SCRATCHPAD: //a bit is sending case OWM_READ_ROM: //a bit is sending SET_TIME(OWT_LOWTIME); break; case OWM_CHK_RESET: //rising edge of reset pulse SET_FALLING; SET_TIME(OWT_RESET_PRESENCE); //waiting for sending presence pulse lmode = OWM_RESET; break; } EN_TIMER; mode = lmode; wmode = lwmode; EXTI->PR |= EXTI_PR_PR12; }
/****************************************************************************** * The timer interrupt service routine */ __irq void TIM1_BRK_TIM15_IRQHandler(void) { uint8_t lwmode = wmode; //let this variables in registers uint8_t lmode = mode; uint8_t lbytep = bytep; uint8_t lbitp = bitp; uint8_t lsrcount = srcount; uint8_t lactbit = actbit; uint8_t lscrc = scrc; //Ask input line sate uint8_t p; p = OW_PIN; //Interrupt still active ? if(CHK_INT_EN){ //maybe reset pulse if(p == 0){ lmode = OWM_CHK_RESET; //wait for rising edge SET_RISING; } DIS_TIMER; }else switch(lmode){ case OWM_RESET: //Reset pulse and time after is finished, now go in presence state lmode = OWM_PRESENCE; SET_LOW; SET_TIME(OWT_PRESENCE); DIS_OWINT; //No Pin interrupt necessary only wait for presence is done break; case OWM_PRESENCE: RESET_LOW; //Presence is done now wait for a command lmode = OWM_READ_COMMAND; cbuf = 0;lbitp = 1; //Command buffer have to set zero, only set bits will write in break; case OWM_READ_COMMAND: if(p){ //Set bit if line high cbuf|= lbitp; } lbitp = (lbitp<<1); if(!lbitp){ //8-Bits read lbitp = 1; switch(cbuf){ //case OWCOM_SKIP_ROM: case OWCOM_READ_ROM: //READ_ROM lmode = OWM_READ_ROM; lbytep = 0; //From first position lactbit = (lbitp & sps_owid[0]) == lbitp; lwmode = lactbit; //Prepare for send firs bit break; case OWCOM_MATCH_ROM: lbytep = 0; lmode = OWM_MATCH_ROM; break; case OWCOM_SEARCH_ROM: //Initialize search rom lmode = OWM_SEARCH_ROM; lsrcount = 0; lbytep = 0; lactbit = (sps_owid[lbytep] & lbitp) == lbitp; //Sset actual bit lwmode = lactbit; //Prepare for writing when next falling edge break; case OWCOM_WRITE_SCRATCHPAD: lmode = OWM_WRITE_SCRATCHPAD; lbytep = 0; lscrc = 0; bffForWriteScr[0] = 0; break; case OWCOM_READ_SCRATCHPAD: //READ_SCRATCHPAD lmode = OWM_READ_SCRATCHPAD; lbytep = 0; lscrc = 0; //From first position lactbit = (lbitp & scratchpad[0]) == lbitp; lwmode = lactbit; //Prepare for send firs bit break; default: lmode = OWM_SLEEP; //all other commands do nothing } } break; case OWCOM_SKIP_ROM: lmode = OWM_READ_COMMAND; break; case OWM_READ_ROM: RESET_LOW; lbitp = (lbitp << 1); if(lbitp == 0){ lbytep++; lbitp = 1; if(lbytep >= OWID_BUF_SIZE){ lmode = OWM_SLEEP; break; } } lactbit = (lbitp & sps_owid[lbytep]) == lbitp; lwmode = lactbit; break; case OWM_SEARCH_ROM: RESET_LOW; //Set low also if nothing send (branch takes time and memory) lsrcount++; //next search rom mode switch(lsrcount){ case 1:lwmode = !lactbit; //preparation sending complement break; case 3: if(p != (lactbit == 1)){ //check master bit lmode = OWM_SLEEP; //not the same go sleep }else{ lbitp = (lbitp << 1); //prepare next bit if(lbitp == 0){ lbitp = 1; lbytep++; if(lbytep >= 8){ lmode = OWM_SLEEP; //all bits processed break; } } lsrcount = 0; lactbit = (sps_owid[lbytep]&lbitp) == lbitp; lwmode = lactbit; } break; } break; case OWM_MATCH_ROM: if(p == ((sps_owid[lbytep] & lbitp) == lbitp)){ //Compare with ID Buffer lbitp = (lbitp<<1); if (lbitp == 0){ lbytep++; lbitp = 1; if(lbytep >= 8){ lmode = OWM_READ_COMMAND; //same? get next command cbuf = 0; break; } } }else{ lmode = OWM_SLEEP; } break; case OWM_WRITE_SCRATCHPAD: if(p != 0){ bffForWriteScr[lbytep] |= lbitp; } if(lbytep < (wrSz - 1)){ if((lscrc&1) != p) lscrc = (lscrc>>1) ^ 0x8c; else lscrc >>= 1; } lbitp = (lbitp << 1); if(lbitp == 0){ lbytep++; lbitp = 1; if(lbytep == wrSz){ if(bffForWriteScr[wrSz - 1] == lscrc){ memcpy((uint8_t*)&spStr.bitTask, (uint8_t*)bffForWriteScr, wrSz); spStr.rxCnt++; }else{ spStr.errCnt++; } lmode = OWM_SLEEP; break; }else{ bffForWriteScr[lbytep] = 0; } } break; case OWM_READ_SCRATCHPAD: RESET_LOW; if((lscrc&1) != lactbit) lscrc = (lscrc>>1) ^ 0x8c; else lscrc >>= 1;
static void event_loop(ACL_EVENT *eventp) { const char *myname = "event_loop"; EVENT_POLL *ev = (EVENT_POLL *) eventp; ACL_EVENT_TIMER *timer; int nready, i, revents; acl_int64 delay; ACL_EVENT_FDTABLE *fdp; delay = eventp->delay_sec * 1000000 + eventp->delay_usec; if (delay < DELAY_MIN) delay = DELAY_MIN; /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); /* 根据定时器任务的最近任务计算 poll 的检测超时上限 */ if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { acl_int64 n = timer->when - eventp->present; if (n <= 0) delay = 0; else if (n < delay) delay = n; } /* 调用 event_prepare 检查有多少个描述字需要通过 poll 进行检测 */ if (event_prepare(eventp) == 0) { /* 说明无须 poll 检测 */ if (eventp->ready_cnt == 0) /* 为避免循环过快,休眠一下 */ acl_doze(delay > DELAY_MIN ? (int) delay / 1000 : 1); goto TAG_DONE; } /* 如果已经有描述字准备好则 poll 检测超时时间置 0 */ if (eventp->ready_cnt > 0) delay = 0; /* 调用 poll 系统调用检测可用描述字 */ nready = poll(ev->fds, eventp->fdcnt, (int) (delay / 1000)); if (eventp->nested++ > 0) { acl_msg_error("%s(%d): recursive call", myname, __LINE__); exit (1); } if (nready < 0) { if (acl_last_error() != ACL_EINTR) { acl_msg_error("%s(%d), %s: select: %s", __FILE__, __LINE__, myname, acl_last_serror()); exit (1); } goto TAG_DONE; } else if (nready == 0) goto TAG_DONE; /* 检查 poll 的检测结果集合 */ for (i = 0; i < eventp->fdcnt; i++) { fdp = acl_fdmap_ctx(ev->fdmap, ev->fds[i].fd); if (fdp == NULL || fdp->stream == NULL) continue; /* 如果该描述字对象已经在被设置为异常或超时状态则继续 */ if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) continue; revents = ev->fds[i].revents; /* 检查描述字是否出现异常 */ if ((revents & (POLLHUP | POLLERR)) != 0) { fdp->event_type |= ACL_EVENT_XCPT; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; continue; } /* 检查描述字是否可读 */ if ((fdp->flag & EVENT_FDTABLE_FLAG_READ) && (revents & POLLIN) ) { /* 给该描述字对象附加可读属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_READ; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } if (fdp->listener) fdp->event_type |= ACL_EVENT_ACCEPT; /* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而 * 触发 ACL_VSTREAM 流在读时调用系统的 read 函数 */ else fdp->stream->read_ready = 1; } /* 检查描述字是否可写 */ if ((fdp->flag & EVENT_FDTABLE_FLAG_WRITE) && (revents & POLLOUT)) { /* 给该描述字对象附加可写属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_WRITE; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } } } TAG_DONE: event_timer_trigger(eventp); /* 处理准备好的描述字事件 */ if (eventp->ready_cnt > 0) event_fire(eventp); eventp->nested--; }
//Finds vertical edges and stores in edgeArray //Vertical edge array is the size of the image, transposed, and contains vertical edge transition features void QRFinder::FindEdgesVerticalClosed(const Mat & inputImg, int xPosition) { const short maxRow = inputImg.rows - detectorSize; if (xPosition < 1 || xPosition >= inputImg.cols - 1) return; if (calculatedEdges.count(xPosition) != 0 && calculatedEdges.at(xPosition)) //This column has already been completely calculated return; struct timespec start,end; SET_TIME(&start); Mat tmpEdgeArray = Mat::zeros(1,inputImg.rows,CV_16S); //Located and scored edges short * edgeRowPtr = tmpEdgeArray.ptr<short>(0); short * outputEdgeRowPtr; for (int i=xPosition-1;i <= xPosition+1;i++) { if (calculatedEdges.count(i) != 0) continue; outputEdgeRowPtr = verticalEdgeArray.ptr<short>(i); for (int j=detectorSize;j < maxRow;j++) { edgeRowPtr[j] = -((short)inputImg.at<unsigned char>((j-1),i) + (short)inputImg.at<unsigned char>((j-2),i)) + (short)inputImg.at<unsigned char>((j+1),i) + (short)inputImg.at<unsigned char>((j+2),i); if (j > (detectorSize + 1) && edgeRowPtr[j-1] != 0 && abs(edgeRowPtr[j-1]) > edgeThreshold && ( !nonMaxEnabled || ( abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j-2]) && abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j]) ) ) ) { outputEdgeRowPtr[j-1] = (edgeRowPtr[j-1] < 0) ? -1 : 1; } else { outputEdgeRowPtr[j-1] = 0; } } calculatedEdges[i] = false; } outputEdgeRowPtr = verticalEdgeArray.ptr<short>(xPosition+1); short * lastOutputRow = verticalEdgeArray.ptr<short>(xPosition); short * beforeLastOutputRow = verticalEdgeArray.ptr<short>(xPosition-1); for (int j=detectorSize;j < maxRow;j++) { if (lastOutputRow[j-1] == 0 && (outputEdgeRowPtr[j-2] != 0 || outputEdgeRowPtr[j-1] != 0 || outputEdgeRowPtr[j] != 0) && (beforeLastOutputRow[j-2] != 0 || beforeLastOutputRow[j-1] != 0 || beforeLastOutputRow[j] != 0)) lastOutputRow[j-1] = outputEdgeRowPtr[j-1] * 2; } calculatedEdges[xPosition] = true; SET_TIME(&end); //LOG_TIME_PRECISE("VerticalEdgeTest",start,end); }
static void event_loop(ACL_EVENT *eventp) { const char *myname = "event_loop"; EVENT_KERNEL *ev = (EVENT_KERNEL *) eventp; ACL_EVENT_NOTIFY_TIME timer_fn; void *timer_arg; ACL_EVENT_TIMER *timer; int delay; ACL_EVENT_FDTABLE *fdp; delay = (int) (eventp->delay_sec * 1000 + eventp->delay_usec / 1000); if (delay < 0) delay = 0; /* 0 milliseconds at least */ SET_TIME(eventp->present); /* * Find out when the next timer would go off. Timer requests are sorted. * If any timer is scheduled, adjust the delay appropriately. */ if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { acl_int64 n = (timer->when - eventp->present) / 1000; if (n <= 0) delay = 0; else if ((int) n < delay) delay = (int) n; } eventp->nested++; event_set_all(eventp); if (eventp->fdcnt == 0) { if (eventp->fdcnt_ready == 0) sleep(1); goto TAG_DONE; } if (eventp->fdcnt_ready > 0) delay = 0; TAG_DONE: /* * Deliver timer events. Requests are sorted: we can stop when we reach * the future or the list end. Allow the application to update the timer * queue while it is being called back. To this end, we repeatedly pop * the first request off the timer queue before delivering the event to * the application. */ SET_TIME(eventp->present); while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { if (timer->when > eventp->present) break; timer_fn = timer->callback; timer_arg = timer->context; /* 如果定时器的时间间隔 > 0 且允许定时器被循环调用,则再重设定时器 */ if (timer->delay > 0 && timer->keep) { timer->ncount++; eventp->timer_request(eventp, timer->callback, timer->context, timer->delay, timer->keep); } else { acl_ring_detach(&timer->ring); /* first this */ timer->nrefer--; if (timer->nrefer != 0) acl_msg_fatal("%s(%d): nrefer(%d) != 0", myname, __LINE__, timer->nrefer); acl_myfree(timer); } timer_fn(ACL_EVENT_TIME, eventp, timer_arg); } for (;;) { BOOL isSuccess = FALSE; DWORD bytesTransferred = 0; DWORD iocpKey = 0; DWORD lastError = 0; IOCP_EVENT *iocp_event = NULL; isSuccess = GetQueuedCompletionStatus(ev->h_iocp, &bytesTransferred, (DWORD*) &fdp, (OVERLAPPED**) &iocp_event, delay); if (!isSuccess) { if (iocp_event == NULL) break; if (iocp_event->type == IOCP_EVENT_DEAD) acl_myfree(iocp_event); else if (iocp_event->fdp == NULL) { acl_msg_warn("%s(%d): fdp null", myname, __LINE__); acl_myfree(iocp_event); } else if (iocp_event->fdp != fdp) acl_msg_fatal("%s(%d): invalid fdp", myname, __LINE__); else if (!(fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) { fdp->event_type |= ACL_EVENT_XCPT; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready] = fdp; eventp->fdcnt_ready++; } continue; } acl_assert(fdp == iocp_event->fdp); if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) { continue; } if (iocp_event->type == IOCP_EVENT_READ) { acl_assert(fdp->event_read == iocp_event); iocp_event->type &= ~IOCP_EVENT_READ; fdp->stream->sys_read_ready = 1; if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_READ; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready] = fdp; eventp->fdcnt_ready++; } } if (iocp_event->type == IOCP_EVENT_WRITE) { acl_assert(fdp->event_write == iocp_event); iocp_event->type &= ~IOCP_EVENT_WRITE; if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_WRITE; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready] = fdp; eventp->fdcnt_ready++; } } delay = 0; } if (eventp->fdcnt_ready > 0) event_fire(eventp); eventp->nested--; }
void QRFinder::FindFinderPatterns(cv::Mat& inputImg, Rect regionOfInterest, vector<FinderPattern*> & finderPatterns, vector<Drawable*> & debugVector) { struct timespec start,end; SET_TIME(&start); //Get parameters from config edgeThreshold = config->GetIntegerParameter("EdgeThreshold"); debugLevel = config->GetIntegerParameter("QR Debug Level"); int verticalResolution = config->GetIntegerParameter("YResolution"); nonMaxEnabled = config->GetBooleanParameter("EdgeNonMax"); minimumFinderPatternScore = config->GetIntegerParameter("MinimumFPScore"); detectorSize = config->GetIntegerParameter("DetectorSize"); int yBorder = detectorSize; vector<Point3i> exclusionZones; //Calculate limits int maxColumn = regionOfInterest.x + regionOfInterest.width; maxColumn -= detectorSize; int maxRow = regionOfInterest.y + regionOfInterest.height; int xStart = regionOfInterest.x; int yStart = regionOfInterest.y; xStart += detectorSize; yStart += detectorSize; maxColumn -= detectorSize; maxRow -= detectorSize; if (debugLevel > 0) debugVector.push_back(new DebugRectangle(Rect(Point2i(xStart,yStart),Point2i(maxColumn,maxRow)),Colors::Aqua,1)); //Find horizontal edges SET_TIME(&start); FindEdgesClosed(inputImg,regionOfInterest,edgeArray,edgeThreshold,nonMaxEnabled,detectorSize); SET_TIME(&end); double edgeTime_local = calc_time_double(start,end); edgeTime = (edgeTime + edgeTime_local)/2.0; config->SetLabelValue("EdgeTime",(float)edgeTime/1000.0f); //If debug level set, find all vertical edges and draw them if (debugLevel <= -2) { for (int x = 1; x < verticalEdgeArray.rows-1; x ++) { FindEdgesVerticalClosed(inputImg,x); const short * verticalEdgePtr = verticalEdgeArray.ptr<short>(x); for (int y = 0; y < (verticalEdgeArray.cols);y++) { short transition = verticalEdgePtr[y]; if (transition < 0) { debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Fuchsia,true)); } else if (transition > 0) { debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Cyan,true)); } } } } //END int bw[6] = { 0 }; int k = 0; //LOGV(LOGTAG_QR,"ImgSize=[%d,%d] EdgeSize=[%d,%d]",inputImg.rows,inputImg.cols,edgeArray.rows,edgeArray.cols); int yDirection = 1; int yCenter = yStart + (maxRow - yStart)/2; int y = yStart, absOffset = 0; LOGV(LOGTAG_QR,"Beginning search. y[%d->%d], Center=%d, x[%d->%d]",yStart,maxRow,yCenter,xStart,maxColumn); while (y < maxRow && y >= yStart) { y = yCenter + absOffset * yDirection; if (yDirection == 1) absOffset += verticalResolution; //Increment every other frame yDirection = -yDirection; //Change direction every frame k = 0; bw[0] = bw[1] = bw[2] = bw[3] = bw[4] = bw[5] = 0; const short * edgeRowPtr = edgeArray.ptr<short>(y); for (int x = xStart; x < maxColumn; x++) { if (isInRadius(exclusionZones,Point2i(x,y))) continue; int transition = edgeRowPtr[x]; //getTransition(Mi,x,threshold); if (k == 0) //Haven't found edge yet { if (transition < 0) /* Light->dark transistion */ { k++; } } else //Found at least one edge { if ((k & 1) == 1) //Counting dark { if (transition > 0) //dark to light { ++k; } } else //Counting light { if (transition < 0) //light to dark { ++k; } } } if (k > 0) ++bw[k-1]; if (FP_DEBUG_ENABLED && (debugLevel == -1 || debugLevel == -2)) { if (transition < 0) debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Lime,true)); else if (transition > 0) debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Yellow,true)); } if (k == 6) { int result = 0; result = CheckRatios(bw,NULL); if (result == 1) { //LOGV(LOGTAG_QR,"Ratio check pass"); //Center based on initial ratio float patternCenterWidth = (float)bw[2]; int tempXCenter = (x - bw[4] - bw[3]) - (int)round(patternCenterWidth/2.0f); float xOffset = (patternCenterWidth/6.0f); //y coordinate of center. If check fails, returns 0. int tempYCenterArray[] = {0,0,0}; int * verticalPatternSizes[3]; for (int i = 0;i < 3;i++) verticalPatternSizes[i] = new int[5]; tempYCenterArray[0] = FindCenterVertical(inputImg, tempXCenter, y, bw, debugVector,verticalPatternSizes[0]); tempYCenterArray[1] = FindCenterVertical(inputImg, tempXCenter - xOffset, y, bw, debugVector,verticalPatternSizes[1]); tempYCenterArray[2] = FindCenterVertical(inputImg, tempXCenter + xOffset, y, bw, debugVector,verticalPatternSizes[2]); int tempYCenter = 0; int passCount = 0; float avgYSize = 0; int averageVerticalSize[5] = {0,0,0,0,0}; for (int yTest = 0; yTest < 3; yTest++) { if (tempYCenterArray[yTest] > 0) { passCount++; tempYCenter += tempYCenterArray[yTest]; for (int i=0;i<5;i++) { averageVerticalSize[i] += (verticalPatternSizes[yTest])[i]; avgYSize += (verticalPatternSizes[yTest])[i]; } } } if (passCount >= 2) { //LOGV(LOGTAG_QR,"Vertical test pass-1"); tempYCenter = (int)round((float)tempYCenter / (float)passCount); avgYSize = (float)avgYSize / (float)passCount; int allowedVariance = (int)avgYSize >> 2; bool yVarianceTest = true; for (int yTest = 0; yTest < 3; yTest++) { if (tempYCenterArray[yTest] > 0) { if (abs(tempYCenterArray[yTest] - tempYCenter) > allowedVariance) { yVarianceTest = false; break; } } } if (yVarianceTest) { //LOGV(LOGTAG_QR,"Vertical test pass-2. Passcount=%d",passCount); //Average the vertical pattern sizes for (int i=0;i<5;i++) { averageVerticalSize[i] = idiv(averageVerticalSize[i],passCount); } //LOGV(LOGTAG_QR,"Averaged sizes. Center=%d",averageVerticalSize[2]); int tempXCenterArray[] = {0,0,0}; int xSizeArray[] = {0,0,0}; int yOffset = idiv(averageVerticalSize[2],6.0f); //LOGV(LOGTAG_QR,"Yoffset=%d,yCenter=%d",yOffset,tempYCenter); tempXCenterArray[0] = FindCenterHorizontal(tempXCenter, tempYCenter-yOffset, bw, xSizeArray[0], debugVector); tempXCenterArray[1] = FindCenterHorizontal(tempXCenter, tempYCenter, bw, xSizeArray[1], debugVector); tempXCenterArray[2] = FindCenterHorizontal(tempXCenter, tempYCenter+yOffset, bw, xSizeArray[2], debugVector); tempXCenter = 0; passCount = 0; float avgXSize = 0; for (int xTest = 0; xTest < 3; xTest++) { if (tempXCenterArray[xTest] > 0) { passCount++; tempXCenter += tempXCenterArray[xTest]; avgXSize += xSizeArray[xTest]; } } if (passCount >= 2) { //LOGV(LOGTAG_QR,"Horizontal test pass"); tempXCenter = (int)round((float)tempXCenter / (float)passCount); avgXSize = (float)avgXSize/(float)passCount; //allowedVariance = (int)round((float)avgYSize/1.5f); float aspectRatio = avgXSize/avgYSize; if (aspectRatio > 0.33f && aspectRatio < 3.0f) { //LOGV(LOGTAG_QR,"Size test pass"); Point2i finderPatternCenter = Point2i(tempXCenter,tempYCenter); //Center of finder pattern int finderPatternSize = MAX(avgXSize,avgYSize); int fpRadius = (int)round((float)finderPatternSize/2.0f); int fpRadiusExclude = ipow(finderPatternSize,2); //LOGD(LOGTAG_QR,"Creating new pattern[%d,%d]",avgXSize,avgYSize); //Create a new pattern FinderPattern * newPattern = new FinderPattern(finderPatternCenter,Size2i(avgXSize,avgYSize)); Size2f patternSearchSize = Size2f(avgXSize,avgYSize); vector<Point2i> corners; struct timespec fastStart,fastEnd; SET_TIME(&fastStart); fastQRFinder->LocateFPCorners(inputImg,newPattern,corners,debugVector); // fastQRFinder->CheckAlignmentPattern(inputImg,finderPatternCenter,patternSearchSize,corners,debugVector); SET_TIME(&fastEnd); double fastFPTime_Local = calc_time_double(fastStart,fastEnd); fastFPTime += fastFPTime_Local; if (corners.size() == 4) { //if (validatePattern(newPattern,finderPatterns)) //{ newPattern->patternCorners = corners; exclusionZones.push_back(Point3i(finderPatternCenter.x,finderPatternCenter.y, fpRadiusExclude)); finderPatterns.push_back(newPattern); if (FP_DEBUG_ENABLED && debugLevel > 0) { debugVector.push_back(new DebugCircle(finderPatternCenter,fpRadius,Colors::MediumSpringGreen,1,true)); for (int i=0;i<corners.size();i++) { if (FP_DEBUG_ENABLED && debugLevel > 0) debugVector.push_back(new DebugCircle(corners[i],10,Colors::DodgerBlue,2)); } } //} //else //{ // //LOGV(LOGTAG_QR,"Compare check failed"); // if (FP_DEBUG_ENABLED && debugLevel > 0) // debugVector.push_back(new DebugCircle(finderPatternCenter,fpRadius,Colors::HotPink,2)); //} } else { //LOGV(LOGTAG_QR,"FAST check failed"); if (FP_DEBUG_ENABLED && debugLevel > 0) debugVector.push_back(new DebugCircle(finderPatternCenter,fpRadius,Colors::Red,2)); delete newPattern; } } else { //LOGV(LOGTAG_QR,"Size check failed"); //Size check failed if (FP_DEBUG_ENABLED && debugLevel > 1) debugVector.push_back(new DebugCircle(Point2i(tempXCenter,tempYCenter),13, Colors::HotPink,1)); } } else { //LOGV(LOGTAG_QR,"Horizontal check failed"); //Vertical check succeeded, but horizontal re-check failed if (FP_DEBUG_ENABLED && debugLevel > 1) debugVector.push_back(new DebugCircle(Point2i(tempXCenter,tempYCenter),12, Colors::OrangeRed,1)); } } else { //LOGV(LOGTAG_QR,"Variance test failed. AllowedVariance = %d, yCenters = %d,%d,%d [avg=%d], AvgYSize=%d",allowedVariance,tempYCenterArray[0],tempYCenterArray[1],tempYCenterArray[2],tempYCenter,avgYSize); //Vertical variance test failed if (FP_DEBUG_ENABLED && debugLevel > 1) debugVector.push_back(new DebugCircle(Point2i(tempXCenter,tempYCenter),14, Colors::MediumSpringGreen,1)); } } else { //Ratios were correct but vertical check failed if (FP_DEBUG_ENABLED && debugLevel > 2) { if (tempYCenter == 0) //ratio fail debugVector.push_back(new DebugCircle(Point2i(tempXCenter,y),10,Colors::Aqua,1)); else if (tempYCenter == -1) //topcheck fail debugVector.push_back(new DebugCircle(Point2i(tempXCenter,y),10,Colors::Orange,1)); else if (tempYCenter == -2) //bottomcheck fail debugVector.push_back(new DebugCircle(Point2i(tempXCenter,y),10,Colors::Lime,1)); } } }
static void event_loop(ACL_EVENT *eventp) { const char *myname = "event_loop"; EVENT_SELECT_THR *event_thr = (EVENT_SELECT_THR *) eventp; ACL_EVENT_NOTIFY_FN worker_fn; void *worker_arg; ACL_SOCKET sockfd; ACL_EVENT_TIMER *timer; int select_delay, nready, i; ACL_EVENT_FDTABLE *fdp; ACL_RING timer_ring, *entry_ptr; struct timeval tv, *tvp; fd_set rmask; /* enabled read events */ fd_set wmask; /* enabled write events */ fd_set xmask; /* for bad news mostly */ acl_ring_init(&timer_ring); SET_TIME(eventp->event_present); THREAD_LOCK(&event_thr->event.tm_mutex); /* * Find out when the next timer would go off. Timer requests are sorted. * If any timer is scheduled, adjust the delay appropriately. */ if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { select_delay = (int) (timer->when - eventp->event_present + 1000000 - 1) / 1000000; if (select_delay < 0) { select_delay = 0; } else if (eventp->delay_sec >= 0 && select_delay > eventp->delay_sec) { select_delay = eventp->delay_sec; } } else { select_delay = eventp->delay_sec; } THREAD_UNLOCK(&event_thr->event.tm_mutex); THREAD_LOCK(&event_thr->event.tb_mutex); if (event_thr_prepare(eventp) == 0) { if (eventp->fdcnt_ready == 0) { if (select_delay <= 0) select_delay = 1; sleep(select_delay); } THREAD_UNLOCK(&event_thr->event.tb_mutex); goto TAG_DONE; } if (eventp->fdcnt_ready > 0) { tv.tv_sec = 0; tv.tv_usec = 0; tvp = &tv; } else if (select_delay < 0) { tvp = NULL; } else { tv.tv_sec = select_delay; tv.tv_usec = eventp->delay_usec; tvp = &tv; } rmask = event_thr->rmask; wmask = event_thr->wmask; xmask = event_thr->xmask; THREAD_UNLOCK(&event_thr->event.tb_mutex); event_thr->event.blocked = 1; nready = select(eventp->maxfd + 1, &rmask, &wmask, &xmask, tvp); event_thr->event.blocked = 0; if (nready < 0) { if (acl_last_error() != ACL_EINTR) { char ebuf[256]; acl_msg_fatal("%s(%d), %s: event_loop: select: %s", __FILE__, __LINE__, myname, acl_last_strerror(ebuf, sizeof(ebuf))); } goto TAG_DONE; } else if (nready == 0) goto TAG_DONE; THREAD_LOCK(&event_thr->event.tb_mutex); for (i = 0; i < eventp->fdcnt; i++) { fdp = eventp->fdtabs[i]; /* if fdp has been set in eventp->fdtabs_ready ? */ if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) continue; sockfd = ACL_VSTREAM_SOCK(fdp->stream); if (FD_ISSET(sockfd, &xmask)) { fdp->event_type |= ACL_EVENT_XCPT; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp; continue; } if (FD_ISSET(sockfd, &rmask)) { fdp->stream->sys_read_ready = 1; /* has been set in fdtabs_ready ? */ if ((fdp->event_type & ACL_EVENT_READ) == 0) { fdp->event_type |= ACL_EVENT_READ; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp; } } else if (fdp->w_callback && FD_ISSET(sockfd, &wmask)) { fdp->event_type |= ACL_EVENT_WRITE; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp; } } THREAD_UNLOCK(&event_thr->event.tb_mutex); TAG_DONE: /* * Deliver timer events. Requests are sorted: we can stop when we reach * the future or the list end. Allow the application to update the timer * queue while it is being called back. To this end, we repeatedly pop * the first request off the timer queue before delivering the event to * the application. */ SET_TIME(eventp->event_present); THREAD_LOCK(&event_thr->event.tm_mutex); while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { if (timer->when > eventp->event_present) break; acl_ring_detach(&timer->ring); /* first this */ acl_ring_prepend(&timer_ring, &timer->ring); } THREAD_UNLOCK(&event_thr->event.tm_mutex); while (1) { entry_ptr = acl_ring_pop_head(&timer_ring); if (entry_ptr == NULL) break; timer = ACL_RING_TO_TIMER(entry_ptr); worker_fn = timer->callback; worker_arg = timer->context; worker_fn(ACL_EVENT_TIME, worker_arg); acl_myfree(timer); } event_thr_fire(eventp); }
static int load_lex(LEXICON *lex, char *tab) { int ret; SPIPlanPtr SPIplan; Portal SPIportal; bool moredata = TRUE; #ifdef DEBUG struct timeval t1, t2; double elapsed; #endif char *sql; int ntuples; int total_tuples = 0; lex_columns_t lex_columns = {seq: -1, word: -1, stdword: -1, token: -1}; int seq; char *word; char *stdword; int token; DBG("start load_lex\n"); SET_TIME(t1); if (!tab || !strlen(tab)) { elog(NOTICE, "load_lex: rules table is not usable"); return -1; } if (!tableNameOk(tab)) { elog(NOTICE, "load_lex: lex and gaz table names may only be alphanum and '.\"_' characters (%s)", tab); return -1; } sql = SPI_palloc(strlen(tab)+65); strcpy(sql, "select seq, word, stdword, token from "); strcat(sql, tab); strcat(sql, " order by id "); /* get the sql for the lexicon records and prepare the query */ SPIplan = SPI_prepare(sql, 0, NULL); if (SPIplan == NULL) { elog(NOTICE, "load_lex: couldn't create query plan for the lex data via SPI (%s)", sql); return -1; } /* get the sql for the lexicon records and prepare the query */ SPIplan = SPI_prepare(sql, 0, NULL); if (SPIplan == NULL) { elog(NOTICE, "load_lex: couldn't create query plan for the lexicon data via SPI"); return -1; } if ((SPIportal = SPI_cursor_open(NULL, SPIplan, NULL, NULL, true)) == NULL) { elog(NOTICE, "load_lex: SPI_cursor_open('%s') returns NULL", sql); return -1; } while (moredata == TRUE) { //DBG("calling SPI_cursor_fetch"); SPI_cursor_fetch(SPIportal, TRUE, TUPLIMIT); if (SPI_tuptable == NULL) { elog(NOTICE, "load_lex: SPI_tuptable is NULL"); return -1; } if (lex_columns.seq == -1) { ret = fetch_lex_columns(SPI_tuptable, &lex_columns); if (ret) return ret; } ntuples = SPI_processed; //DBG("Reading edges: %i - %i", total_tuples, total_tuples+ntuples); total_tuples += ntuples; if (ntuples > 0) { int t; Datum binval; bool isnull; SPITupleTable *tuptable = SPI_tuptable; TupleDesc tupdesc = SPI_tuptable->tupdesc; for (t = 0; t < ntuples; t++) { //if (t%100 == 0) { DBG(" t: %i", t); } HeapTuple tuple = tuptable->vals[t]; GET_INT_FROM_TUPLE(seq,lex_columns.seq,"load_lex: seq contains a null value"); GET_TEXT_FROM_TUPLE(word,lex_columns.word); GET_TEXT_FROM_TUPLE(stdword,lex_columns.stdword); GET_INT_FROM_TUPLE(token,lex_columns.token,"load_lex: token contains a null value"); lex_add_entry(lex, seq, word, stdword, token); } //DBG("calling SPI_freetuptable"); SPI_freetuptable(tuptable); //DBG("back from SPI_freetuptable"); } else moredata = FALSE; } SET_TIME(t2); ELAPSED_T(t1, t2); DBG("Time to read %i lexicon records: %.1f ms.", total_tuples, elapsed); return 0; } static int fetch_rules_columns(SPITupleTable *tuptable, rules_columns_t *rules_cols) { int err = 0; FETCH_COL(rules_cols,rule,"rule"); if (err) { elog(NOTICE, "rules queries must return column 'rule'"); return -1; } CHECK_TYP(rules_cols,rule,TEXTOID); if (err) { elog(NOTICE, "rules column type must be: 'rule' text"); return -1; } return 0; }
void AugmentedView::Render(OpenGL * openGL) { if (!canDraw) return; OpenGLRenderData renderData = openGL->renderData; struct timespec start,end; SET_TIME(&start); SetCameraPosition(renderData); OpenGLSettings(); SelectedObject * newSelection = SelectObjects(openGL); struct timespec now; SET_TIME(&now); double timediff = calc_time_double(lastSelectionTime,now); if (unselectNext) { if (selectedObject != NULL) UpdateObjectPosition(projection,selectedObject); unselectNext = false; } //Only allowed to change selections every 1.0 seconds else if (newSelection != NULL && timediff > 800000.0) { //Unselect object if selected twice if (selectedObject != NULL && selectedObject->arObject == newSelection->arObject) { UpdateObjectPosition(projection,selectedObject); } else { delete selectedObject; selectedObject = newSelection; // //Point3f cameraPosition = getCameraPosition(projection); //Point3f cameraOffset = selectedObject->arObject->position - cameraPosition; ////Initial offset between object and camera selectedObject->objectPositionDelta = getObjectScreenCoord(selectedObject->arObject->position,projection);//scameraOffset; projection.copyTo(selectedObject->originalProjectionMat); cancelSelection->SetVisible(true); releaseSelection->SetVisible(true); //LOGD(LOGTAG_ARINPUT,"CameraPositionOffset(%f,%f,%f)",cameraOffset.x,cameraOffset.y,cameraOffset.z); } lastSelectionTime = now; }else if (newSelection != NULL) { LOGD(LOGTAG_ARINPUT,"Time spacing too short for unselect. Diff=%lf",timediff); } SET_TIME(&now); bool popVector = false; timediff = calc_time_double(cursorShowTime,now); if (timediff < 5000000.0) { objectVector.push_back(testObject); popVector = true; } LOGV(LOGTAG_OPENGL,"Drawing %d ARObjects",objectVector.size()); for (int i=0;i<objectVector.size();i++) { ARObject * object = objectVector.at(i); //LOGV(LOGTAG_OPENGL,"Drawing ARObject at (%f,%f,%f)",object->position.x,object->position.y,object->position.z); //LOGV(LOGTAG_OPENGL,"With rotation (%f,%f,%f)",object->rotation.x,object->rotation.y,object->rotation.z); Mat modelMatrix = Mat::eye(4,4,CV_32F); if (selectedObject != NULL && selectedObject->arObject == object) { //Point3f cameraPosition = getCameraPosition(projection); selectedObject->arObject->position = getObject3DCoord(selectedObject->objectPositionDelta,projection);//selectedObject->objectPositionDelta + cameraPosition; /* Point3f cameraRotation = getCameraRotation(); selectedObject->arObject->rotation = selectedObject->objectRotationDelta + cameraRotation; */ } OpenGLHelper::translate(modelMatrix,Point3f(object->position.x,object->position.y,object->position.z)); OpenGLHelper::rotate(modelMatrix,object->rotation.x, Point3f(1.0f, 0.0f, 0.0f)); OpenGLHelper::rotate(modelMatrix,object->rotation.y, Point3f(0.0f, 1.0f, 0.0f)); OpenGLHelper::rotate(modelMatrix,object->rotation.z, Point3f(0.0f, 0.0f, 1.0f)); Mat tmpModelMatrix; //Use seperate scale for selection indicator if (selectedObject != NULL && selectedObject->arObject == object) { modelMatrix.copyTo(tmpModelMatrix); } OpenGLHelper::scale(modelMatrix,object->scale); Mat mt = Mat(modelMatrix.t()); glUniformMatrix4fv(renderData.modelMatrixLocation, 1, GL_FALSE, mt.ptr<float>(0)); openGL->DrawGLObject(object->glObject); if (selectedObject != NULL && selectedObject->arObject == object) { float selectorSize = object->BoundingSphereRadius*2.25f; OpenGLHelper::scale(tmpModelMatrix,Point3f(selectorSize,selectorSize,selectorSize)); Mat mt = Mat(tmpModelMatrix.t()); glUniformMatrix4fv(renderData.modelMatrixLocation, 1, GL_FALSE, mt.ptr<float>(0)); openGL->DrawGLObject(selectionIndicator->glObject); } } //Get rid of test object if (popVector) objectVector.pop_back(); ResetGLSettings(); SET_TIME(&end); LOG_TIME("AugmentedView Render",start,end); canDraw = false; }
SelectedObject * AugmentedView::SelectObjects(OpenGL * openGL) { vector<Point2i> currentPoints = inputPoints; inputPoints.clear(); SelectedObject * found = NULL; while (!currentPoints.empty()) { Point3f p1,p2; getPickingRay(currentPoints.back(),openGL,projection,p1,p2,testObject,fieldOfView); vector<ARObject*> hitObjects; Point3f p12 = p2-p1; //LOGD(LOGTAG_ARINPUT,"P12=(%f,%f,%f)",p12.x,p12.y,p12.z); float p12Mag = pow(p12.x,2) + pow(p12.y,2) + pow(p12.z,2); for (int i=0;i<objectVector.size();i++) { Point3f p0 = objectVector[i]->position; //Mat position = Mat(1,3,CV_32F); Point3f cross = p12.cross((p1-p0)); float distance = pow(cross.x,2) + pow(cross.y,2) + pow(cross.z,2); distance /= p12Mag; distance = sqrt(distance); if (distance < objectVector[i]->BoundingSphereRadius) { hitObjects.push_back(objectVector[i]); } else { LOGV(LOGTAG_ARINPUT,"Did not collide with object %s at position %f,%f,%f with sphere of radius %f (distance=%f)", objectVector[i]->objectID.c_str(),p0.x,p0.y,p0.z,objectVector[i]->BoundingSphereRadius,distance); } } if (hitObjects.size() > 0) { if (hitObjects.size() > 1) { std::sort(hitObjects.begin(),hitObjects.end(),ARObjectDistanceSort_Ascending(p1)); } struct timespec now; SET_TIME(&now); cursorShowTime.tv_sec = 0; //hide cursor if selection successful found = new SelectedObject(hitObjects.front(),now); break; } else { currentPoints.pop_back(); } if (found == NULL) SET_TIME(&cursorShowTime); } return found; }
static int load_rules(RULES *rules, char *tab) { int ret; SPIPlanPtr SPIplan; Portal SPIportal; bool moredata = TRUE; #ifdef DEBUG struct timeval t1, t2; double elapsed; #endif char *sql; int rule_arr[MAX_RULE_LENGTH]; int ntuples; int total_tuples = 0; rules_columns_t rules_columns = {rule: -1}; char *rule; DBG("start load_rules\n"); SET_TIME(t1); if (!tab || !strlen(tab)) { elog(NOTICE, "load_rules: rules table is not usable"); return -1; } if (!tableNameOk(tab)) { elog(NOTICE, "load_rules: rules table name may only be alphanum and '.\"_' characters (%s)", tab); return -1; } sql = SPI_palloc(strlen(tab)+35); strcpy(sql, "select rule from "); strcat(sql, tab); strcat(sql, " order by id "); /* get the sql for the lexicon records and prepare the query */ SPIplan = SPI_prepare(sql, 0, NULL); if (SPIplan == NULL) { elog(NOTICE, "load_rules: couldn't create query plan for the rule data via SPI (%s)", sql); return -1; } if ((SPIportal = SPI_cursor_open(NULL, SPIplan, NULL, NULL, true)) == NULL) { elog(NOTICE, "load_rules: SPI_cursor_open('%s') returns NULL", sql); return -1; } while (moredata == TRUE) { //DBG("calling SPI_cursor_fetch"); SPI_cursor_fetch(SPIportal, TRUE, TUPLIMIT); if (SPI_tuptable == NULL) { elog(NOTICE, "load_rules: SPI_tuptable is NULL"); return -1; } if (rules_columns.rule == -1) { ret = fetch_rules_columns(SPI_tuptable, &rules_columns); if (ret) return ret; } ntuples = SPI_processed; //DBG("Reading edges: %i - %i", total_tuples, total_tuples+ntuples); if (ntuples > 0) { int t; SPITupleTable *tuptable = SPI_tuptable; TupleDesc tupdesc = SPI_tuptable->tupdesc; for (t = 0; t < ntuples; t++) { int nr; //if (t%100 == 0) { DBG(" t: %i", t); } HeapTuple tuple = tuptable->vals[t]; GET_TEXT_FROM_TUPLE(rule,rules_columns.rule); nr = parse_rule(rule, rule_arr); if (nr == -1) { elog(NOTICE, "load_roles: rule exceeds 128 terms"); return -1; } ret = rules_add_rule(rules, nr, rule_arr); if (ret != 0) { elog(NOTICE,"load_roles: failed to add rule %d (%d): %s", total_tuples+t+1, ret, rule); return -1; } } //DBG("calling SPI_freetuptable"); SPI_freetuptable(tuptable); //DBG("back from SPI_freetuptable"); } else moredata = FALSE; total_tuples += ntuples; } ret = rules_ready(rules); if (ret != 0) { elog(NOTICE, "load_roles: failed to ready the rules: err: %d", ret); return -1; } SET_TIME(t2); ELAPSED_T(t1, t2); DBG("Time to read %i rule records: %.1f ms.", total_tuples, elapsed); return 0; }
static void event_loop(ACL_EVENT *eventp) { const char *myname = "event_loop"; EVENT_SELECT *ev = (EVENT_SELECT *) eventp; ACL_EVENT_NOTIFY_TIME timer_fn; void *timer_arg; ACL_SOCKET sockfd; ACL_EVENT_TIMER *timer; int nready, i; acl_int64 delay; ACL_EVENT_FDTABLE *fdp; struct timeval tv, *tvp; fd_set rmask; /* enabled read events */ fd_set wmask; /* enabled write events */ fd_set xmask; /* for bad news mostly */ delay = eventp->delay_sec * 1000000 + eventp->delay_usec; /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); /* 根据定时器任务的最近任务计算 select 的检测超时上限 */ if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { acl_int64 n = timer->when - eventp->present; if (n <= 0) delay = 0; else if (n < delay) delay = n; } /* 调用 event_prepare 检查有多少个描述字需要通过 select 进行检测 */ if (event_prepare(eventp) == 0) { if (eventp->ready_cnt == 0) { delay /= 1000000; if (delay <= 0) delay = 1; /* 为避免循环过快,休眠一下 */ sleep((int) delay); } goto TAG_DONE; } if (eventp->ready_cnt > 0) { tv.tv_sec = 0; tv.tv_usec = 0; tvp = &tv; } else if (delay >= 0) { #if defined(ACL_WINDOWS) tv.tv_sec = (long) delay / 1000000; tv.tv_usec = (unsigned long) (delay - tv.tv_sec * 1000000); #else tv.tv_sec = (time_t) delay / 1000000; tv.tv_usec = (suseconds_t) (delay - tv.tv_sec * 1000000); #endif tvp = &tv; } else tvp = NULL; rmask = ev->rmask; wmask = ev->wmask; xmask = ev->xmask; /* 调用 select 系统调用检测可用描述字 */ #ifdef ACL_WINDOWS nready = select(0, &rmask, &wmask, &xmask, tvp); #else nready = select(eventp->maxfd + 1, &rmask, &wmask, &xmask, tvp); #endif if (eventp->nested++ > 0) acl_msg_fatal("%s(%d): recursive call(%d)", myname, __LINE__, eventp->nested); if (nready < 0) { if (acl_last_error() != ACL_EINTR) { acl_msg_fatal("%s(%d), %s: select: %s", __FILE__, __LINE__, myname, acl_last_serror()); } goto TAG_DONE; } else if (nready == 0) goto TAG_DONE; /* 检查 select 的检测结果集合 */ /* if some fdp was cleared from eventp->fdtabs in timer callback, * which has no effection on the rest fdp in eventp->fdtabs */ for (i = 0; i < eventp->fdcnt; i++) { fdp = eventp->fdtabs[i]; /* 如果该描述字对象已经在被设置为异常或超时状态则继续 */ if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) continue; sockfd = ACL_VSTREAM_SOCK(fdp->stream); /* 检查描述字是否出现异常 */ if (FD_ISSET(sockfd, &xmask)) { fdp->event_type |= ACL_EVENT_XCPT; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; continue; } /* 检查描述字是否可读 */ if (FD_ISSET(sockfd, &rmask)) { /* 给该描述字对象附加可读属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_READ; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } if (fdp->listener) fdp->event_type |= ACL_EVENT_ACCEPT; /* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而 * 触发 ACL_VSTREAM 流在读时调用系统的 read 函数 */ else fdp->stream->read_ready = 1; } /* 检查描述字是否可写 */ if (FD_ISSET(sockfd, &wmask)) { /* 给该描述字对象附加可写属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_WRITE; fdp->fdidx_ready = eventp->ready_cnt; eventp->ready[eventp->ready_cnt++] = fdp; } } } TAG_DONE: /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); /* 优先处理定时器中的任务 */ while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { if (timer->when > eventp->present) break; timer_fn = timer->callback; timer_arg = timer->context; /* 如果定时器的时间间隔 > 0 且允许定时器被循环调用, * 则再重设定时器 */ if (timer->delay > 0 && timer->keep) { timer->ncount++; eventp->timer_request(eventp, timer->callback, timer->context, timer->delay, timer->keep); } else { acl_ring_detach(&timer->ring); /* first this */ timer->nrefer--; if (timer->nrefer != 0) acl_msg_fatal("%s(%d): nrefer(%d) != 0", myname, __LINE__, timer->nrefer); acl_myfree(timer); } timer_fn(ACL_EVENT_TIME, eventp, timer_arg); } /* 处理准备好的描述字事件 */ if (eventp->ready_cnt > 0) event_fire(eventp); eventp->nested--; }
int main() { RTTIMESPEC Now; RTTIMESPEC Ts1; RTTIMESPEC Ts2; RTTIME T1; RTTIME T2; #ifdef RTTIME_INCL_TIMEVAL struct timeval Tv1; struct timeval Tv2; struct timespec Tsp1; struct timespec Tsp2; #endif RTTEST hTest; int rc = RTTestInitAndCreate("tstRTTimeSpec", &hTest); if (rc) return rc; /* * Simple test with current time. */ RTTestSub(hTest, "Current time (UTC)"); CHECK_NZ(RTTimeNow(&Now)); CHECK_NZ(RTTimeExplode(&T1, &Now)); RTTestIPrintf(RTTESTLVL_ALWAYS, " %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1)); CHECK_NZ(RTTimeImplode(&Ts1, &T1)); if (!RTTimeSpecIsEqual(&Ts1, &Now)) RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now)); /* * Simple test with current local time. */ RTTestSub(hTest, "Current time (local)"); CHECK_NZ(RTTimeLocalNow(&Now)); CHECK_NZ(RTTimeExplode(&T1, &Now)); RTTestIPrintf(RTTESTLVL_ALWAYS, " %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1)); CHECK_NZ(RTTimeImplode(&Ts1, &T1)); if (!RTTimeSpecIsEqual(&Ts1, &Now)) RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now)); /* * Some simple tests with fixed dates (just checking for smoke). */ RTTestSub(hTest, "Smoke"); TEST_NS(INT64_C(0)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); TEST_NS(INT64_C(86400000000000)); CHECK_TIME(&T1, 1970,01,02, 00,00,00, 0, 2, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); TEST_NS(INT64_C(1)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 1, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); TEST_NS(INT64_C(-1)); CHECK_TIME(&T1, 1969,12,31, 23,59,59,999999999, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* * Test the limits. */ RTTestSub(hTest, "Extremes"); TEST_NS(INT64_MAX); TEST_NS(INT64_MIN); TEST_SEC(1095379198); CHECK_TIME(&T1, 2004, 9,16, 23,59,58, 0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); TEST_SEC(1095379199); CHECK_TIME(&T1, 2004, 9,16, 23,59,59, 0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); TEST_SEC(1095379200); CHECK_TIME(&T1, 2004, 9,17, 00,00,00, 0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); TEST_SEC(1095379201); CHECK_TIME(&T1, 2004, 9,17, 00,00,01, 0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); /* * Test normalization (UTC). */ RTTestSub(hTest, "Normalization (UTC)"); /* simple */ CHECK_NZ(RTTimeNow(&Now)); CHECK_NZ(RTTimeExplode(&T1, &Now)); T2 = T1; CHECK_NZ(RTTimeNormalize(&T1)); if (memcmp(&T1, &T2, sizeof(T1))) RTTestIFailed("simple normalization failed\n"); CHECK_NZ(RTTimeImplode(&Ts1, &T1)); CHECK_NZ(RTTimeSpecIsEqual(&Ts1, &Now)); /* a few partial dates. */ memset(&T1, 0, sizeof(T1)); SET_TIME( &T1, 1970,01,01, 00,00,00, 0, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1970,00,00, 00,00,00, 1, 1, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1970,01,01, 00,00,00, 1, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2007,12,06, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1968,01,30, 00,19,24, 5, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1968,01,30, 00,19,24, 5, 30, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 1969,01,31, 00, 9, 2, 7, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,01,31, 00, 9, 2, 7, 31, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,03,31, 00, 9, 2, 7, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,03,31, 00, 9, 2, 7, 90, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,31, 00,00,00, 9, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,31, 00,00,00, 9, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,30, 00,00,00, 30, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,30, 00,00,00, 30, 364, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 363, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,29, 00,00,00, 30, 363, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 362, 6, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,28, 00,00,00, 30, 362, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,27, 00,00,00, 30, 0, 5, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,27, 00,00,00, 30, 361, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,00,00, 00,00,00, 30, 360, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,26, 00,00,00, 30, 360, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,25, 00,00,00, 12, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,25, 00,00,00, 12, 359, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 1969,12,24, 00,00,00, 16, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1969,12,24, 00,00,00, 16, 358, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* outside the year table range */ SET_TIME( &T1, 1200,01,30, 00,00,00, 2, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1200,01,30, 00,00,00, 2, 30, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 2555,11,29, 00,00,00, 2, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2555,11,29, 00,00,00, 2, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2555,00,00, 00,00,00, 3, 333, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2555,11,29, 00,00,00, 3, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* time overflow */ SET_TIME( &T1, 1969,12,30, 255,255,255, UINT32_MAX, 364, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 1970,01, 9, 19,19,19,294967295, 9, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* date overflow */ SET_TIME( &T1, 2007,11,36, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2007,10,67, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2007,10,98, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2008,01,06, 02,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 2006,24,06, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); SET_TIME( &T1, 2003,60,37, 02,15,23, 1, 0, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2008,01,06, 02,15,23, 1, 6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); SET_TIME( &T1, 2003,00,00, 02,15,23, 1,1801, 0, 0, 0); CHECK_NZ(RTTimeNormalize(&T1)); CHECK_TIME(&T1, 2007,12,06, 02,15,23, 1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); /* * Conversions. */ #define CHECK_NSEC(Ts1, T2) \ do { \ RTTIMESPEC TsTmp; \ RTTESTI_CHECK_MSG( RTTimeSpecGetNano(&(Ts1)) == RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2))), \ ("line %d: %RI64, %RI64\n", __LINE__, \ RTTimeSpecGetNano(&(Ts1)), RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2)))) ); \ } while (0) RTTestSub(hTest, "Conversions, positive"); SET_TIME(&T1, 1980,01,01, 00,00,00, 0, 1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); RTTESTI_CHECK(RTTimeSpecSetDosSeconds(&Ts2, 0) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetDosSeconds(&Ts2) == 0); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1980,01,01, 00,00,00, 0, 1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR); RTTESTI_CHECK(RTTimeSpecSetNtTime(&Ts2, INT64_C(119600064000000000)) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetNtTime(&Ts2) == INT64_C(119600064000000000)); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetSeconds(&Ts2, 1) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetSeconds(&Ts2) == 1); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetMilli(&Ts2, 1000) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetMilli(&Ts2) == 1000); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetMicro(&Ts2, 1000000) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000000); CHECK_NSEC(Ts2, T1); SET_TIME(&T1, 1970,01,01, 00,00,01, 0, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); RTTESTI_CHECK(RTTimeSpecSetNano(&Ts2, 1000000000) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000000); CHECK_NSEC(Ts2, T1); #ifdef RTTIME_INCL_TIMEVAL SET_TIME(&T1, 1970,01,01, 00,00,01, 5000, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tv1.tv_sec = 1; Tv1.tv_usec = 5; RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000005); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2); RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec); #endif #ifdef RTTIME_INCL_TIMESPEC SET_TIME(&T1, 1970,01,01, 00,00,01, 5, 1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tsp1.tv_sec = 1; Tsp1.tv_nsec = 5; RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2); RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000005); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2); RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec); #endif RTTestSub(hTest, "Conversions, negative"); #ifdef RTTIME_INCL_TIMEVAL SET_TIME(&T1, 1969,12,31, 23,59,58,999995000, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tv1.tv_sec = -2; Tv1.tv_usec = 999995; RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2); RTTESTI_CHECK_MSG(RTTimeSpecGetMicro(&Ts2) == -1000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2))); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2); RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec); #endif #ifdef RTTIME_INCL_TIMESPEC SET_TIME(&T1, 1969,12,31, 23,59,58,999999995, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR); Tsp1.tv_sec = -2; Tsp1.tv_nsec = 999999995; RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2); RTTESTI_CHECK_MSG(RTTimeSpecGetNano(&Ts2) == -1000000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2))); CHECK_NSEC(Ts2, T1); RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2); RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec); #endif /* * Summary */ return RTTestSummaryAndDestroy(hTest); }
static void event_loop(ACL_EVENT *eventp) { const char *myname = "event_loop"; EVENT_KERNEL *ev = (EVENT_KERNEL *) eventp; ACL_EVENT_NOTIFY_TIME timer_fn; void *timer_arg; ACL_EVENT_TIMER *timer; int delay, nready; ACL_EVENT_FDTABLE *fdp; EVENT_BUFFER *bp; delay = (int) (eventp->delay_sec * 1000 + eventp->delay_usec / 1000); if (delay < 0) delay = 0; /* 0 milliseconds at least */ /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); /* 根据定时器任务的最近任务计算 epoll/kqueue/devpoll 的检测超时上限 */ if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { acl_int64 n = (timer->when - eventp->present) / 1000; if (n <= 0) delay = 0; else if ((int) n < delay) { delay = (int) n; if (delay <= 0) /* xxx */ delay = 100; } } /* 设置描述字对象的状态,添加/删除之前设置的描述字对象 */ event_set_all(eventp); if (eventp->fdcnt == 0) { if (eventp->fdcnt_ready == 0) sleep(1); goto TAG_DONE; } /* 如果已经有描述字准备好则检测超时时间置 0 */ if (eventp->fdcnt_ready > 0) delay = 0; /* 调用 epoll/kquque/devpoll 系统调用检测可用描述字 */ EVENT_BUFFER_READ(nready, ev->event_fd, ev->event_buf, ev->event_fdslots, delay); if (eventp->nested++ > 0) acl_msg_fatal("%s(%d): recursive call, nested: %d", myname, __LINE__, eventp->nested); if (nready < 0) { if (acl_last_error() != ACL_EINTR) { acl_msg_fatal("%s(%d), %s: select: %s", __FILE__, __LINE__, myname, acl_last_serror()); } goto TAG_DONE; } else if (nready == 0) goto TAG_DONE; /* 检查检测结果 */ for (bp = ev->event_buf; bp < ev->event_buf + nready; bp++) { #ifdef USE_FDMAP ACL_SOCKET sockfd; sockfd = EVENT_GET_FD(bp); fdp = acl_fdmap_ctx(ev->fdmap, sockfd); if (fdp == NULL || fdp->stream == NULL) continue; if (sockfd != ACL_VSTREAM_SOCK(fdp->stream)) acl_msg_fatal("%s(%d): sockfd(%d) != %d", myname, __LINE__, sockfd, ACL_VSTREAM_SOCK(fdp->stream)); #else fdp = (ACL_EVENT_FDTABLE *) EVENT_GET_CTX(bp); if (fdp == NULL || fdp->stream == NULL) continue; #endif /* 如果该描述字对象已经在被设置为异常或超时状态则继续 */ if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT))) continue; /* 检查描述字是否可读 */ if ((fdp->flag & EVENT_FDTABLE_FLAG_READ) && EVENT_TEST_READ(bp)) { /* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而触发 * ACL_VSTREAM 流在读时调用系统的 read 函数 */ fdp->stream->sys_read_ready = 1; /* 给该描述字对象附加可读属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_READ; if (fdp->listener) fdp->event_type |= ACL_EVENT_ACCEPT; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp; } } /* 检查描述字是否可写 */ if ((fdp->flag & EVENT_FDTABLE_FLAG_WRITE) && EVENT_TEST_WRITE(bp)) { /* 给该描述字对象附加可写属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_WRITE; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp; } } #ifdef EVENT_TEST_ERROR if (EVENT_TEST_ERROR(bp)) { /* 如果出现异常则设置异常属性 */ if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0) { fdp->event_type |= ACL_EVENT_XCPT; fdp->fdidx_ready = eventp->fdcnt_ready; eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp; } } #endif } TAG_DONE: /* * Deliver timer events. Requests are sorted: we can stop when we reach * the future or the list end. Allow the application to update the timer * queue while it is being called back. To this end, we repeatedly pop * the first request off the timer queue before delivering the event to * the application. */ /* 调整事件引擎的时间截 */ SET_TIME(eventp->present); while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) { if (timer->when > eventp->present) break; timer_fn = timer->callback; timer_arg = timer->context; /* 定时器时间间隔 > 0 且允许定时器被循环调用,则重设定时器 */ if (timer->delay > 0 && timer->keep) { timer->ncount++; eventp->timer_request(eventp, timer->callback, timer->context, timer->delay, timer->keep); } else { acl_ring_detach(&timer->ring); /* first this */ timer->nrefer--; if (timer->nrefer != 0) acl_msg_fatal("%s(%d): nrefer(%d) != 0", myname, __LINE__, timer->nrefer); acl_myfree(timer); } timer_fn(ACL_EVENT_TIME, eventp, timer_arg); } /* 处理准备好的描述字事件 */ if (eventp->fdcnt_ready > 0) event_fire(eventp); eventp->nested--; }
void ARController::ProcessFrame(Engine * engine) { if (!isInitialized) return; frameCount++; //Calc FPS struct timespec currentTime; SET_TIME(¤tTime); double frameTimeMicrosec = calc_time_double(lastFrameTime,currentTime); lastFrameTime = currentTime; float frameFps = (float)(1000000.0/frameTimeMicrosec); fpsAverage = (fpsAverage+frameFps)/2.0f; char fpsString[10]; sprintf(fpsString,"%3.1f",fpsAverage); fpsLabel->SetText(fpsString); int debugLevel = debugUI->GetIntegerParameter("ARControllerDebug"); bool useGuess = debugUI->GetBooleanParameter("UseGuess"); bool showEntireBinary = debugUI->GetBooleanParameter("Show Entire Binary"); //This section is the default per-frame operations FrameItem * item = frameList->next(); item->clearOldData(); //engine->getTime(&item->time); LOGV(LOGTAG_ARCONTROLLER,"Processing frame #%d, FPS=%f.",frameCount,fpsAverage); //Loose objects: QR=%d, Rect=%d, Circ=%d, FP=%d", //frameCount,fpsAverage,(int)QRCode::instanceCount,DebugRectangle::instanceCount,DebugCircle::instanceCount, FinderPattern::instanceCount); //If paused, keep reusing image until unpaused if (!paused) { getImages(engine); } else { //Need to refresh the RGB image cvtColor(*grayImage, *rgbImage, CV_GRAY2RGBA, 4); } vector<Drawable*> debugVector; item->qrCode = qrFinder->LocateQRCodes(*grayImage, debugVector, ( frameList->size() > 1) ? frameList->getRelative(-1)->qrCode : NULL); //What happens past here depends on the state if (controllerState == ControllerStates::Loading) { //Update world loader worldLoader->Update(engine); WorldStates::WorldState worldState = worldLoader->GetState(); if (worldState == WorldStates::LookingForCode) { debugUI->SetLabelValue("State","Searching"); if (item->qrCode != NULL && item->qrCode->isValidCode()) { struct timespec decodeStart,decodeEnd; SET_TIME(&decodeStart); qrDecoder->DecodeQRCode(grayImage,binaryImage,item->qrCode,debugVector); SET_TIME(&decodeEnd); LOG_TIME("Decode",decodeStart,decodeEnd); if (item->qrCode->isDecoded()) { string codeText = "Code="; codeText.append(item->qrCode->TextValue); debugUI->SetLabelValue("CurrentCode",codeText); currentCode = item->qrCode->TextValue; if (debugUI->GetBooleanParameter("CodeOnly")) { LOGI(LOGTAG_ARCONTROLLER,"Code found (%s), still searching since we're in debug mode",currentCode.c_str()); } else if (engine->communicator->IsConnected()) { worldLoader->LoadRealm(item->qrCode->TextValue); } else //If not connected, just add a test object { LOGI(LOGTAG_ARCONTROLLER,"Starting in offline mode."); debugUI->SetLabelValue("State","OfflineMode"); initializeARView(engine); ARObject * myCube1 = new ARObject(OpenGLHelper::CreateMultiColorCube(20),Point3f(0,0,0)); //ARObject * myCube2 = new ARObject(OpenGLHelper::CreateMultiColorCube(20),Point3f(50,10,0)); //augmentedView->AddObject(myCube2); //myCube2->BoundingSphereRadius = 30; //ARObject * myCube3 = new ARObject(OpenGLHelper::CreateMultiColorCube(20),Point3f(-50,-10,0)); //augmentedView->AddObject(myCube3); //myCube3->BoundingSphereRadius = 30; augmentedView->AddObject(myCube1); myCube1->BoundingSphereRadius = 12; SetState(ControllerStates::Running); delete worldLoader; worldLoader = NULL; } } else LOGD(LOGTAG_ARCONTROLLER,"QRCode not decoded"); } } else if (worldState == WorldStates::WaitingForRealm || worldState == WorldStates::WaitingForResources) { if (worldState == WorldStates::WaitingForRealm) debugUI->SetLabelValue("State","WaitRealm"); else debugUI->SetLabelValue("State","WaitRsrc"); } //The world is ready and loaded, so do normal AR processing else if (worldState == WorldStates::WorldReady) { debugUI->SetLabelValue("State","LoadCompl"); initializeARView(engine); LOGD(LOGTAG_ARCONTROLLER,"Populating ARView using loaded world"); worldLoader->PopulateARView(augmentedView); SetState(ControllerStates::Running); currentQRSize = debugUI->GetParameter("QRSize"); //Should be using value from server delete worldLoader; worldLoader = NULL; } else { char stateString[100]; sprintf(stateString,"WrldState=%d",(int)worldState); debugUI->SetLabelValue("State",stateString); LOGW(LOGTAG_ARCONTROLLER,"Unexpected state"); } } else if (controllerState == ControllerStates::Running) { debugUI->SetLabelValue("State","Run"); bool doSkip = false; if (item->qrCode != NULL && item->qrCode->isValidCode()) { if (recheckNext) { LOGD(LOGTAG_ARCONTROLLER,"Rechecking code. Current value = %s",currentCode.c_str()); qrDecoder->DecodeQRCode(grayImage,binaryImage,item->qrCode,debugVector); if (item->qrCode->isDecoded() && item->qrCode->TextValue != currentCode) { if (worldLoader == NULL) worldLoader = new WorldLoader(); else { delete worldLoader; worldLoader = new WorldLoader(); } LOGD(LOGTAG_ARCONTROLLER,"Changing to code %s",currentCode.c_str()); currentCode = item->qrCode->TextValue; worldLoader->LoadRealm(currentCode); SetState(ControllerStates::Loading); delete augmentedView; augmentedView = NULL; recheckNext = false; doSkip = true; } else if (item->qrCode->isDecoded()) recheckNext = false; } else { if (useGuess) positionSelector->GetPreviousResult(item); LOGV(LOGTAG_QR,"Getting position"); currentQRSize = debugUI->GetParameter("QRSize"); //Should be using value from server item->qrCode->QRCodeDimension = currentQRSize; qrLocator->transformPoints(item->qrCode,*(item->rotationMatrix),*(item->translationMatrix),useGuess); debugUI->SetTranslation(item->translationMatrix); debugUI->SetRotation(item->rotationMatrix); } } certaintyIndicator->EnableOutline(recheckNext); if (!doSkip) { //Evaluate the position float resultCertainty = positionSelector->UpdatePosition(engine,item); certaintyIndicator->SetCertainty(resultCertainty); if (resultCertainty > 0 && augmentedView != NULL) { augmentedView->SetFOV(debugUI->GetParameter("FOV")); augmentedView->SetTransformations(item->translationMatrix,item->rotationMatrix,item->gyroRotation); } if (augmentedView != NULL) augmentedView->Update(rgbImage,engine); } } else { char stateString[100]; sprintf(stateString,"ContState=%d",(int)controllerState); debugUI->SetLabelValue("State",stateString); LOGW(LOGTAG_ARCONTROLLER,"Unexpected state: %s",stateString); } if (debugUI->currentDrawMode == DrawModes::BinaryImage) { if (showEntireBinary) { ImageProcessor::SimpleThreshold(grayImage,binaryImage); cvtColor(*binaryImage, *rgbImage, CV_GRAY2RGBA, 4); } else { LOGD(LOGTAG_ARCONTROLLER,"Binary debug draw"); cvtColor(*binaryImage, *rgbImage, CV_GRAY2RGBA, 4); LOGD(LOGTAG_ARCONTROLLER,"Binary debug draw complete"); } } if (drawingLevel == 1 || drawingLevel == 3) { if (item->qrCode != NULL) { item->qrCode->SetDrawingLevel(debugLevel); item->qrCode->Draw(rgbImage); } struct timespec draw_start, draw_end; SET_TIME(&draw_start); while (!debugVector.empty()) { debugVector.back()->Draw(rgbImage); delete debugVector.back(); debugVector.pop_back(); } SET_TIME(&draw_end); LOG_TIME_PRECISE("DebugDrawing",draw_start,draw_end); } else //Still need to clean up debug vector!!!! { struct timespec draw_start, draw_end; SET_TIME(&draw_start); while (!debugVector.empty()) { delete debugVector.back(); debugVector.pop_back(); } SET_TIME(&draw_end); LOG_TIME_PRECISE("DebugCleanup",draw_start,draw_end); } //Do final processing Draw(rgbImage); }