/** * Receives a packet from the GameController. * Packets are only accepted when the team number is know (nonzero) and * they are addressed to this team. */ bool receive() { bool received = false; int size; RoboCupGameControlData buffer; struct sockaddr_in from; while(udp && (size = udp->read((char*) &buffer, sizeof(buffer), from)) > 0) { if(size == sizeof(buffer) && !std::memcmp(&buffer, GAMECONTROLLER_STRUCT_HEADER, 4) && buffer.version == GAMECONTROLLER_STRUCT_VERSION && teamNumber && (buffer.teams[0].teamNumber == teamNumber || buffer.teams[1].teamNumber == teamNumber)) { gameCtrlData = buffer; if(memcmp(&gameControllerAddress, &from.sin_addr, sizeof(in_addr))) { memcpy(&gameControllerAddress, &from.sin_addr, sizeof(in_addr)); udp->setTarget(inet_ntoa(gameControllerAddress), GAMECONTROLLER_RETURN_PORT); } received = true; } } return received; }
/** * The constructor sets up the structures required to communicate with NAOqi. * @param pBroker A NAOqi broker that allows accessing other NAOqi modules. */ GameCtrl(boost::shared_ptr<AL::ALBroker> pBroker) : ALModule(pBroker, "GameCtrl"), proxy(0), memory(0), udp(0), teamNumber(0) { setModuleDescription("A module that provides packets from the GameController."); assert(numOfButtons == sizeof(buttonNames) / sizeof(*buttonNames)); assert(numOfLEDs == sizeof(ledNames) / sizeof(*ledNames)); init(); try { memory = new AL::ALMemoryProxy(pBroker); proxy = new AL::DCMProxy(pBroker); AL::ALValue params; AL::ALValue result; params.arraySetSize(1); params.arraySetSize(2); params[0] = std::string("leds"); params[1].arraySetSize(numOfLEDs); for(int i = 0; i < numOfLEDs; ++i) params[1][i] = std::string(ledNames[i]); result = proxy->createAlias(params); assert(result == params); ledRequest.arraySetSize(6); ledRequest[0] = std::string("leds"); ledRequest[1] = std::string("ClearAll"); ledRequest[2] = std::string("time-separate"); ledRequest[3] = 0; ledRequest[4].arraySetSize(1); ledRequest[5].arraySetSize(numOfLEDs); for(int i = 0; i < numOfLEDs; ++i) ledRequest[5][i].arraySetSize(1); for(int i = 0; i < numOfButtons; ++i) buttons[i] = (float*) memory->getDataPtr(buttonNames[i]); playerNumber = (int*) memory->getDataPtr("GameCtrl/playerNumber"); teamNumberPtr = (int*) memory->getDataPtr("GameCtrl/teamNumber"); defaultTeamColour = (int*) memory->getDataPtr("GameCtrl/teamColour"); // register "onPreProcess" and "onPostProcess" callbacks theInstance = this; proxy->getGenericProxy()->getModule()->atPreProcess(&onPreProcess); proxy->getGenericProxy()->getModule()->atPostProcess(&onPostProcess); udp = new UdpComm(); if(!udp->setBlocking(false) || !udp->setBroadcast(true) || !udp->bind("0.0.0.0", GAMECONTROLLER_PORT) || !udp->setTarget(UdpComm::getWifiBroadcastAddress(), GAMECONTROLLER_PORT) || !udp->setLoopback(false)) { fprintf(stderr, "libgamectrl: Could not open UDP port\n"); delete udp; udp = 0; // continue, because button interface will still work } publish(); } catch(AL::ALError& e) { fprintf(stderr, "libgamectrl: %s\n", e.toString().c_str()); close(); } }