HawkFreezer.C

00001 // File: HawkFreezer.C
00002 // Author: Josh Villbrandt <josh.villbrandt@usc.edu>
00003 // Date: April 2010
00004 
00005 #include "Robots/BeoHawk/computer/HawkFreezer.H"
00006 
00007 // ######################################################################
00008 HawkFreezer::HawkFreezer(std::string myName, int argc, char* argv[])
00009 : HawkAgent(myName, argc, argv) {
00010         // Help section
00011         helpTitle = "HawkFreezer";
00012         helpDescription = "Stores ICE messages for future playback. Also plays them back.";
00013         helpOptions.push_back("\t--mode\t\t(record) Should be 'record' or 'playback'.");
00014         helpOptions.push_back("\t--file\t\t(default.freezer) File to read or write from.");
00015         helpOptions.push_back("\t--duration\t(30) Duration to playback or record ICE messages.");
00016         helpOptions.push_back("\t--frequency\t(0) Maximum messages per second to play or record. Set to 0 to ignore this setting.");
00017         
00018         // Parameters
00019         duration = loadDoubleParameter("duration", 30);
00020         frequency = loadDoubleParameter("frequency", 0);
00021         std::string modeString = loadStringParameter("mode", "record");
00022         file = loadStringParameter("file", "default.freezer");
00023         timer = Timer(1000000);
00024         
00025         // Set skip period
00026         if(frequency == 0) period = 0;
00027         else period = 1/frequency;
00028         lastMessageSeconds = timer.getSecs() - period;
00029         
00030         // Set state
00031         if(modeString == "record") {
00032                 std::cout << "starting to record to " << file << " for " << duration << " seconds" << std::endl;
00033                 state = RECORD;
00034         }
00035         else {
00036                 std::cout << "set to playback from " << file << std::endl;
00037                 state = LOAD_PLAYBACK;
00038         }
00039 }
00040 
00041 // ######################################################################
00042 void HawkFreezer::registerTopics() {
00043         registerPublisher("SensorDataMessage");
00044         registerSubscription("SensorDataMessage");
00045 }
00046 
00047 // ######################################################################
00048 bool HawkFreezer::scheduler() {
00049         if(state == RECORD) {
00050                 if(timer.getSecs() < duration) {
00051                         usleep(1000000); // this does not respect non-integer durations, who cares
00052                         std::cout << "captured " << messages.size() << " messages..." << std::endl;
00053                         return true;
00054                 }
00055                 else {
00056                         std::cout << "record duration reached, writing to file..." << std::endl;
00057                         saveMessages();
00058                 }
00059         }
00060         else if(state == LOAD_PLAYBACK) {
00061                 loadMessages();
00062                 return true;
00063         }
00064         else if(state == PLAYBACK) {
00065                 if(messages.size() > 0 && timer.getSecs() < duration) {
00066                         std::cout << messages.size() << " messages left to play..." << std::endl;
00067                         playNextMessages();
00068                         return true;
00069                 }
00070                 else {
00071                         std::cout << "no more messages to play back (or duration elapsed)..." << std::endl;
00072                 }
00073         }
00074         
00075         stop();
00076         return false;
00077 }
00078 
00079 // ######################################################################
00080 void HawkFreezer::catchMessage(const HawkMessages::MessagePtr& hawkMessage, const Ice::Current&) {
00081         if(state == RECORD && hawkMessage->ice_isA("::HawkMessages::SensorDataMessage") && timer.getSecs() > (lastMessageSeconds + period))
00082         {
00083                 // Save message to storage queue
00084                 Message msg;
00085                 msg.sensorData = HawkMessages::SensorDataMessagePtr::dynamicCast(hawkMessage);
00086                 msg.timestamp = timer.getSecs();
00087                 messages.push_back(msg);
00088                 
00089                 // Reset
00090                 lastMessageSeconds = timer.getSecs();
00091         }
00092 }
00093 
00094 // ######################################################################
00095 void HawkFreezer::playNextMessages() {
00096         // Play messages
00097         while(messages.size() > 0 && messages.front().timestamp <= timer.getSecs()) {
00098                 publish("SensorDataMessage", messages.front().sensorData);
00099                 lastMessageSeconds = messages.front().timestamp;
00100                 messages.erase(messages.begin());
00101         }
00102         
00103         // Delete future skipped messages
00104         while(messages.size() > 0 && messages.front().timestamp < (lastMessageSeconds+period)) {
00105                 messages.erase(messages.begin());
00106         }
00107         
00108         // Sleep until next message
00109         if(messages.size() > 0)
00110                 usleep((int)((messages.front().timestamp - timer.getSecs())*1000000));
00111 }
00112 
00113 // ######################################################################
00114 void HawkFreezer::loadMessages() {
00115         std::ifstream fileStream;
00116         fileStream.open(file.c_str());
00117         if(fileStream) {
00118                 // Load number of messages
00119                 int numberOfMessages;
00120                 fileStream >> numberOfMessages;
00121                 
00122                 // Load each message
00123                 for(int i = 0; i < numberOfMessages; i++) {
00124                         Message msg;
00125                         
00126                         // Timestamp
00127                         fileStream >> msg.timestamp;
00128                         
00129                         // Attempted move
00130                         HawkMessages::Pose attemptedMove;
00131                         fileStream >> attemptedMove.x;
00132                         fileStream >> attemptedMove.y;
00133                         fileStream >> attemptedMove.z;
00134                         fileStream >> attemptedMove.theta;
00135                         
00136                         // Scanner data
00137                         double angularResolution;
00138                         fileStream >> angularResolution;
00139                         int scannerDataSize;
00140                         fileStream >> scannerDataSize;
00141                         HawkMessages::LongSeq scannerData;
00142                         long temp;
00143                         for(int j = 0; j < scannerDataSize; j++) {
00144                                 fileStream >> temp;
00145                                 scannerData.push_back(temp);
00146                         }
00147                         
00148                         // Add to message vector
00149                         msg.sensorData = new HawkMessages::SensorDataMessage;
00150                         msg.sensorData->attemptedMove = attemptedMove;
00151                         msg.sensorData->angularResolution = angularResolution;
00152                         msg.sensorData->scannerData = scannerData;
00153                         messages.push_back(msg);
00154                 }
00155                 
00156                 std::cout << "playback file loaded, now starting playback..." << std::endl;
00157                 state = PLAYBACK;
00158         }
00159         else {
00160                 std::cout << "Error: file could not be opened." << std::endl;
00161                 state = INIT_FAIL;
00162         }
00163         fileStream.close();
00164 }
00165 
00166 // ######################################################################
00167 void HawkFreezer::saveMessages() {
00168         std::ofstream fileStream;
00169         fileStream.open(file.c_str());
00170         if(fileStream) {
00171                 // Write number of messages
00172                 fileStream << messages.size() << std::endl;
00173                 
00174                 // Write each message
00175                 for(int i = 0; i < (int)messages.size(); i++) {
00176                         // Timestamp
00177                         fileStream << messages[i].timestamp << std::endl;
00178                         
00179                         // Attempted move
00180                         fileStream << messages[i].sensorData->attemptedMove.x << " ";
00181                         fileStream << messages[i].sensorData->attemptedMove.y << " ";
00182                         fileStream << messages[i].sensorData->attemptedMove.z << " ";
00183                         fileStream << messages[i].sensorData->attemptedMove.theta << std::endl;
00184                         
00185                         // Scanner data
00186                         fileStream << messages[i].sensorData->angularResolution << " ";
00187                         fileStream << messages[i].sensorData->scannerData.size();
00188                         for(int j = 0; j < (int)messages[i].sensorData->scannerData.size(); j++) {
00189                                 fileStream << " " << messages[i].sensorData->scannerData[j];
00190                         }
00191                         fileStream << std::endl;
00192                 }
00193         }
00194         else {
00195                 std::cout << "Error: file could not be opened. That sucks." << std::endl;
00196         }
00197         fileStream.close();
00198 }
00199 
00200 // ######################################################################
00201 int main (int argc, char* argv[]) {
00202         std::cout << "HawkFreezer: starting..." << std::endl;
00203         
00204         HawkFreezer agent("HawkFreezer", argc, argv);
00205         agent.start();
00206         
00207         std::cout << "HawkFreezer: all done!" << std::endl;
00208 }
Generated on Sun May 8 08:41:20 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3