void Server::manageError(QString address, int port, QAbstractSocket::SocketError error){ int playerIndex = getPlayerIndex(address, port); if(networkAnswers[playerIndex].isEmpty()){ nbNetworkAnswers++; } else{ qDebug() << "Server::manageError() : SUPER WEIRD, player sent first message " << networkAnswers[playerIndex] << " then error " << error; } switch(waitingForMessage){ case(WAITING_FOR_MESSAGE::INFO): case(WAITING_FOR_MESSAGE::START): emit playerReady(playerIndex, false); break; case(WAITING_FOR_MESSAGE::PLAY): moves[playerIndex] = ""; break; default: break; } if(nbNetworkAnswers == addresses.size()){ handleTransition(); } emit emitError(playerIndex, error); }
void Server::processMessage(QString address, int port, QString message){ // qDebug() << "\nServer::processMessage()"; int playerIndex = getPlayerIndex(address, port); Q_ASSERT(playerIndex >=0); if(networkAnswers[playerIndex].isEmpty()){ nbNetworkAnswers++; } else{ qDebug() << "Server::processMessage() : SUPER WEIRD, player sent first message " << networkAnswers[playerIndex] << " then message " << message; } networkAnswers[playerIndex] = message; // qDebug() << "Player " << playerIndex << " : " << message; // Send immediate feedback switch(waitingForMessage){ case(WAITING_FOR_MESSAGE::INFO): if(rxPlayerName.indexIn(message)>=0){ emit playerName(playerIndex, rxPlayerName.cap(1)); } if(rxStatusAvailable.indexIn(message) >= 0){ emit playerAvailable(playerIndex, true); } else{ emit playerAvailable(playerIndex, false); } break; case(WAITING_FOR_MESSAGE::START): if(rxReady.indexIn(message) >= 0){ emit playerReady(playerIndex, true); } else{ emit playerReady(playerIndex, false); } break; case(WAITING_FOR_MESSAGE::PLAY): moves[playerIndex] = message; emit outputPlayerMessage(playerIndex, message); break; case(WAITING_FOR_MESSAGE::DONE): if(message != "done"){ manageError(address, port, QAbstractSocket::UnknownSocketError); } emit outputPlayerMessage(playerIndex, message); break; default: break; } // if(nbNetworkAnswers == addresses.size()){ // Finish the job // qDebug() << "Server::processMessage() : Got all the messages"; handleTransition(); } }
void moFlatlandColorPairFinderModule::applyFilter(IplImage *src) { ///////////////////////////////////////////////////////////////////////////////////// //Step 1 get gray version of input, retain colored version ///////////////////////////////////////////////////////////////////////////////////// //Step 2 pass gray along normally to contour finder. this->clearBlobs(); //imagePreprocess(src); //cvCopy(src, this->output_buffer); cvCvtColor(src, this->output_buffer, CV_RGB2GRAY); CvSeq *contours = 0; cvFindContours(this->output_buffer, this->storage, &contours, sizeof(CvContour), CV_RETR_CCOMP); cvDrawContours(this->output_buffer, contours, cvScalarAll(255), cvScalarAll(255), 100); //cvCircle(this->output_buffer, /* the dest image */ // cvPoint(110, 60), 35, /* center point and radius */ // cvScalarAll(255), /* the color; red */ // 1, 8, 0); // Consider each contour a blob and extract the blob infos from it. int size; int min_size = this->property("min_size").asInteger(); int max_size = this->property("max_size").asInteger(); CvSeq *cur_cont = contours; ///////////////////////////////////////////////////////////////////////////////////// //Step 3 check window around contour centers and find color //clear the console? //system("cls"); //system("clear"); //clrscr(); //printf("\033[2J"); //std::cout << std::string( 100, '\n' ); std::vector<ColoredPt> cPts; //printf("==================================\n"); int blobi = 0; while (cur_cont != 0) { CvRect rect = cvBoundingRect(cur_cont, 0); size = rect.width * rect.height; //printf(":: %d\n", size); if ((size >= min_size) && (size <= max_size)) { //TODO use a Vector double red = 0; double green = 0; double blue = 0; int blobColor = 0; //in reality, probably could filter heavily and just look at 1 pixel, or at least a very small window // [!!!] for (int x = rect.x; x < rect.x + rect.width; x++) { for (int y = rect.y; y < rect.y + rect.height; y++) { int blueVal = ( ((uchar*)(src->imageData + src->widthStep*y))[x*3+0] ); int greenVal = ( ((uchar*)(src->imageData + src->widthStep*y))[x*3+1] ); int redVal = ( ((uchar*)(src->imageData + src->widthStep*y))[x*3+2] ); double colorNorm = 1.0;//sqrt((blueVal*blueVal) + (greenVal*greenVal) + (redVal * redVal)); //weight dark pixels less double weight = 1.0;//(1.0*blueVal + greenVal + redVal) / (1.5 * 255.0); if (weight > 1) { weight = 1; } if (colorNorm > 0) { red += weight*redVal/colorNorm; green += weight*greenVal/colorNorm; blue += weight*blueVal/colorNorm; } } } //the channel totals //printf("%d : %f\n%f\n%f\n\n",blobi , red, green, blue); blobi++; if (red > green && red > blue) { blobColor = RED; } if (blue > green && blue > red) { blobColor = BLUE; } if (green > red && green > blue) { blobColor = GREEN; } blobColor = matchColor(red, green, blue); // Draw a letter corresponding to the LED color CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, .7f, .7f, 0, 1, CV_AA); if (blobColor == RED) { cvPutText(this->output_buffer, "R", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0), &font, cvScalar(255, 255, 255, 0)); } else if (blobColor == GREEN) { cvPutText(this->output_buffer, "G", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0), &font, cvScalar(255, 255, 255, 0)); } else if (blobColor == BLUE) { cvPutText(this->output_buffer, "B", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0), &font, cvScalar(255, 255, 255, 0)); } else if (blobColor == WHITE) { cvPutText(this->output_buffer, "Y", cvPoint(rect.x + rect.width / 2.0, rect.y + rect.height / 2.0), &font, cvScalar(255, 255, 255, 0)); } /*moDataGenericContainer *blob = new moDataGenericContainer(); blob->properties["implements"] = new moProperty("pos,size"); blob->properties["x"] = new moProperty((rect.x + rect.width / 2) / (double) src->width ); blob->properties["y"] = new moProperty((rect.y + rect.height / 2) / (double) src->height ); blob->properties["width"] = new moProperty(rect.width); blob->properties["height"] = new moProperty(rect.height); blob->properties["color"] = new moProperty(blobColor); this->blobs->push_back(blob);*/ struct ColoredPt thisPt; thisPt.x = (rect.x + rect.width / 2);// / (double) src->width; thisPt.y = (rect.y + rect.height / 2);// / (double) src->height; thisPt.color = blobColor; cPts.push_back(thisPt); } cur_cont = cur_cont->h_next; } ///////////////////////////////////////////////////////////////////////////////////// //Step 4 iterate over blobs again, to find close pairs //TODO Currently, this algorithm assumes the best, and does nothing to ensure robustness/smoothness //e.g. add a distance threshold (would need to be "settable" in a Gui) int nPlayersFound = 0; //Init the adjacency list int MAX_N_LIGHTS = 20; // TODO! more lights may need to be identified for field markers! int pairs[MAX_N_LIGHTS]; for ( int i = 0; i < MAX_N_LIGHTS; i++ ) { pairs[i] = -1; } //printf("+++++++++++++++++++++++++++++++++++++++++\n"); // map out closest pairs of lights. //TODO need to iterate through blobs and throw out obviously non-player-light blobs. (big blobs) //TODO //TODO //TODO //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // In more realistic scenarios, an arbitrary number of lights is likely to appear! // Need to account for this! //! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! for ( int i = 0; i < cPts.size() && i < MAX_N_LIGHTS; i++ ) // dynamically allocate pairs based on number of lights? { if(pairs[i] == -1) { double minDist = 1000000;//distances are < 1, so should be OK. int closestIdx = -1; for ( int j = i; j < cPts.size() && j < MAX_N_LIGHTS; j++ ) { if (j != i) { double x1 = cPts[i].x; double y1 = cPts[i].y; double x2 = cPts[j].x; double y2 = cPts[j].y; double distance = sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)); if (distance < minDist) { minDist = distance; closestIdx = j; } } } if (closestIdx >= 0) { pairs[i] = closestIdx; pairs[closestIdx] = -9999; //designate as 'slave' point. nPlayersFound ++; //printf("%d ___ %d\n",i, pairs[i]); } } else { } } //printf("==================================\n"); //for ( int i = 0; i < cPts.size(); i++ ) //{ // printf("%d ___ %d\n", i, pairs[i]); //} /////////////////////////////////////// // Clear the player list ////////////// moDataGenericList::iterator pit; for ( pit = this->players->begin(); pit != this->players->end(); pit++ ) { delete (*pit); } this->players->clear(); // look at pair colors and determine player number for (int i = 0; i < MAX_N_LIGHTS; i++) { if (pairs[i] >= 0) { //printf("%d ___ %d\n",pairs[i], pairs[i]); int color1 = cPts[i].color; int color2 = cPts[pairs[i]].color; //write a function to choose the player int playerIdx = getPlayerIndex(color1, color2); std::ostringstream labelStream; labelStream << playerIdx; /*if ((color1 == 0 && color2 == 2) || (color2 == 0 && color1 == 2)) //red and blue { label = "1"; } else if ((color1 == 0 && color2 == 1) || (color2 == 0 && color1 == 1)) //red and green { label = "2"; }*/ double avX = (cPts[i].x + cPts[pairs[i]].x)/2; double avY = (cPts[i].y + cPts[pairs[i]].y)/2; CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.7f, 1.7f, 0, 1, CV_AA); cvPutText(this->output_buffer, labelStream.str().c_str(), cvPoint(avX, avY), &font, cvScalar(255, 255, 255, 0)); /*moDataGenericContainer *player = new moDataGenericContainer(); player->properties["implements"] = new moProperty("pos"); player->properties["x"] = new moProperty(avX / src->width); player->properties["y"] = new moProperty(avY / src->height); player->properties["blob_id"] = new moProperty(playerIdx); std::string implements = player->properties["implements"]->asString(); // Indicate that the blob has been tracked, i.e. blob_id exists. implements += ",tracked"; player->properties["implements"]->set(implements); this->players->push_back(player);*/ //->properties["blob_id"]->set(old_id); } } //Add in some fake players, so I don't have to have the lights out to test the connection. double debugX = .5 + .25 * sin(2*3.14 * frameCounter / 200); if (frameCounter % 2 == 0) { moDataGenericContainer *player = new moDataGenericContainer(); player->properties["implements"] = new moProperty("pos"); player->properties["x"] = new moProperty(debugX); player->properties["y"] = new moProperty(.75); player->properties["blob_id"] = new moProperty(0); std::string implements = player->properties["implements"]->asString(); // Indicate that the blob has been tracked, i.e. blob_id exists. implements += ",tracked"; player->properties["implements"]->set(implements); moDataGenericContainer *player2 = new moDataGenericContainer(); player2->properties["implements"] = new moProperty("pos"); player2->properties["x"] = new moProperty(1 - debugX); player2->properties["y"] = new moProperty(.75); player2->properties["blob_id"] = new moProperty(1); player2->properties["implements"]->set(implements); this->players->push_back(player); this->players->push_back(player2); } frameCounter = (frameCounter + 1) % 200; this->output_data->push(this->players); }