/** * Close all resources acquired. * Called when initialization failed or during destruction. */ void close() { if(udp) delete udp; if(proxy) { proxy->getGenericProxy()->getModule()->removeAllPreProcess(); proxy->getGenericProxy()->getModule()->removeAllPostProcess(); delete proxy; } if(memory) delete memory; }
/** Close all resources acquired. Called when initialization failed or during destruction. */ void close() { fprintf(stderr, "libbhuman: Stopping.\n"); if(proxy) { proxy->getGenericProxy()->getModule()->removeAllPreProcess(); proxy->getGenericProxy()->getModule()->removeAllPostProcess(); delete proxy; } if(memory) delete memory; if(sem != SEM_FAILED) sem_close(sem); if(data != MAP_FAILED) munmap(data, sizeof(LBHData)); fprintf(stderr, "libbhuman: Stopped.\n"); }
/** * 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]); // If no color was set, set it to black (no LED). // This actually has a race condition. if(memory->getDataList("GameCtrl/teamColour").empty()) memory->insertData("GameCtrl/teamColour", TEAM_BLACK); 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_DATA_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.what()); close(); } }
/** * The constructor initializes the shared memory for communicating with bhuman. * It also establishes a communication with NaoQi and prepares all data structures * required for this communication. * @param pBroker A NaoQi broker that allows accessing other NaoQi modules. */ BHuman(boost::shared_ptr<AL::ALBroker> pBroker) : ALModule(pBroker, "BHuman"), data((LBHData*) MAP_FAILED), sem(SEM_FAILED), proxy(0), memory(0), dcmTime(0), lastReadingActuators(-1), actuatorDrops(0), frameDrops(allowedFrameDrops + 1), state(sitting), phase(0.f), ledIndex(0), rightEarLEDsChangedTime(0), startPressedTime(0), lastBHumanStartTime(0) { setModuleDescription("A module that provides basic ipc NaoQi DCM access using shared memory."); fprintf(stderr, "libbhuman: Starting.\n"); assert(lbhNumOfSensorIds == sizeof(sensorNames) / sizeof(*sensorNames)); assert(lbhNumOfActuatorIds == sizeof(actuatorNames) / sizeof(*actuatorNames)); assert(lbhNumOfTeamInfoIds == sizeof(teamInfoNames) / sizeof(*teamInfoNames)); // create shared memory memoryHandle = shm_open(LBH_MEM_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if(memoryHandle == -1) perror("libbhuman: shm_open"); else if(ftruncate(memoryHandle, sizeof(LBHData)) == -1) perror("libbhuman: ftruncate"); else { // map the shared memory data = (LBHData*) mmap(NULL, sizeof(LBHData), PROT_READ | PROT_WRITE, MAP_SHARED, memoryHandle, 0); if(data == MAP_FAILED) perror("libbhuman: mmap"); else { memset(data, 0, sizeof(LBHData)); // open semaphore sem = sem_open(LBH_SEM_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0); if(sem == SEM_FAILED) perror("libbhuman: sem_open"); else try { // get the robot name memory = new AL::ALMemoryProxy(pBroker); std::string robotName = (std::string) memory->getData("Device/DeviceList/ChestBoard/BodyNickName", 0); strncpy(data->robotName, robotName.c_str(), sizeof(data->robotName)); // create "positionRequest" and "hardnessRequest" alias proxy = new AL::DCMProxy(pBroker); AL::ALValue params; AL::ALValue result; params.arraySetSize(1); params.arraySetSize(2); params[0] = std::string("positionActuators"); params[1].arraySetSize(lbhNumOfPositionActuatorIds); for(int i = 0; i < lbhNumOfPositionActuatorIds; ++i) params[1][i] = std::string(actuatorNames[i]); result = proxy->createAlias(params); params[0] = std::string("hardnessActuators"); params[1].arraySetSize(lbhNumOfHardnessActuatorIds); for(int i = 0; i < lbhNumOfHardnessActuatorIds; ++i) params[1][i] = std::string(actuatorNames[headYawHardnessActuator + i]); result = proxy->createAlias(params); params[0] = std::string("usRequest"); params[1].arraySetSize(1); params[1][0] = std::string(actuatorNames[usActuator]); result = proxy->createAlias(params); // prepare positionRequest positionRequest.arraySetSize(6); positionRequest[0] = std::string("positionActuators"); positionRequest[1] = std::string("ClearAll"); positionRequest[2] = std::string("time-separate"); positionRequest[3] = 0; positionRequest[4].arraySetSize(1); positionRequest[5].arraySetSize(lbhNumOfPositionActuatorIds); for(int i = 0; i < lbhNumOfPositionActuatorIds; ++i) positionRequest[5][i].arraySetSize(1); // prepare hardnessRequest hardnessRequest.arraySetSize(6); hardnessRequest[0] = std::string("hardnessActuators"); hardnessRequest[1] = std::string("ClearAll"); hardnessRequest[2] = std::string("time-separate"); hardnessRequest[3] = 0; hardnessRequest[4].arraySetSize(1); hardnessRequest[5].arraySetSize(lbhNumOfHardnessActuatorIds); for(int i = 0; i < lbhNumOfHardnessActuatorIds; ++i) hardnessRequest[5][i].arraySetSize(1); // prepare usRequest usRequest.arraySetSize(6); usRequest[0] = std::string("usRequest"); usRequest[1] = std::string("Merge"); // doesn't work with "ClearAll" usRequest[2] = std::string("time-separate"); usRequest[3] = 0; usRequest[4].arraySetSize(1); usRequest[5].arraySetSize(1); usRequest[5][0].arraySetSize(1); // prepare ledRequest ledRequest.arraySetSize(3); ledRequest[1] = std::string("ClearAll"); ledRequest[2].arraySetSize(1); ledRequest[2][0].arraySetSize(2); ledRequest[2][0][1] = 0; // prepare sensor pointers for(int i = 0; i < lbhNumOfSensorIds; ++i) sensorPtrs[i] = (float*) memory->getDataPtr(sensorNames[i]); resetUsMeasurements(); // initialize requested actuators memset(requestedActuators, 0, sizeof(requestedActuators)); for(int i = faceLedRedLeft0DegActuator; i < chestBoardLedRedActuator; ++i) requestedActuators[i] = -1.f; // register "onPreProcess" and "onPostProcess" callbacks theInstance = this; proxy->getGenericProxy()->getModule()->atPreProcess(&onPreProcess); proxy->getGenericProxy()->getModule()->atPostProcess(&onPostProcess); fprintf(stderr, "libbhuman: Started!\n"); return; // success } catch(AL::ALError& e) { fprintf(stderr, "libbhuman: %s\n", e.toString().c_str()); } } } close(); // error }