play.cpp
Go to the documentation of this file.
00001 /*
00002         Aseba - an event-based framework for distributed robot control
00003         Copyright (C) 2007--2012:
00004                 Stephane Magnenat <stephane at magnenat dot net>
00005                 (http://stephane.magnenat.net)
00006                 and other contributors, see authors.txt for details
00007         
00008         This program is free software: you can redistribute it and/or modify
00009         it under the terms of the GNU Lesser General Public License as published
00010         by the Free Software Foundation, version 3 of the License.
00011         
00012         This program is distributed in the hope that it will be useful,
00013         but WITHOUT ANY WARRANTY; without even the implied warranty of
00014         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015         GNU Lesser General Public License for more details.
00016         
00017         You should have received a copy of the GNU Lesser General Public License
00018         along with this program. If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "../common/consts.h"
00022 #include "../msg/msg.h"
00023 #include "../utils/utils.h"
00024 #include <dashel/dashel.h>
00025 #include "../transport/dashel_plugins/dashel-plugins.h"
00026 #include <time.h>
00027 #include <iostream>
00028 #include <cstring>
00029 #include <string>
00030 #include <deque>
00031 
00032 namespace Aseba
00033 {
00034         using namespace Dashel;
00035         using namespace std;
00036         
00041         
00044         class Player : public Hub
00045         {
00046         private:
00047                 typedef deque<string> StringList;
00048                 
00049                 bool respectTimings;
00050                 int speedFactor;
00051                 Stream* in;
00052                 string line;
00053                 UnifiedTime lastTimeStamp;
00054                 UnifiedTime lastEventTime;
00055         
00056         public:
00057                 Player(const char* inputFile, bool respectTimings, int speedFactor) :
00058                         respectTimings(respectTimings),
00059                         speedFactor(speedFactor),
00060                         lastTimeStamp(0)
00061                 {
00062                         if (inputFile)
00063                                 in = connect("file:" + string(inputFile) + ";mode=read");
00064                         else
00065                                 in = connect("stdin:");
00066                 }
00067                 
00068                 StringList tokenize(const string& input)
00069                 {
00070                         StringList list;
00071                         const size_t inputSize(input.size());
00072                         
00073                         size_t pos(0);
00074                         while ((pos != string::npos) && (pos < inputSize))
00075                         {
00076                                 const size_t next = input.find(' ', pos);
00077                                 string word;
00078                                 if (next != string::npos)
00079                                         word = input.substr(pos, next-pos);
00080                                 else
00081                                         word = input.substr(pos);
00082                                 if (!word.empty())
00083                                         list.push_back(word);
00084                                 pos = next + 1;
00085                         }
00086                         
00087                         return list;
00088                 }
00089                 
00090                 void sendLine()
00091                 {
00092                         // parse line and build user message
00093                         UserMessage userMessage;
00094                         
00095                         StringList tokenizedLine(tokenize(line));
00096                         
00097                         UnifiedTime timeStamp(UnifiedTime::fromRawTimeString(tokenizedLine.front()));
00098                         tokenizedLine.pop_front();
00099                         
00100                         userMessage.source = atoi(tokenizedLine.front().c_str());
00101                         tokenizedLine.pop_front();
00102                         
00103                         userMessage.type = atoi(tokenizedLine.front().c_str());
00104                         tokenizedLine.pop_front();
00105                         
00106                         userMessage.data.reserve(size_t(atoi(tokenizedLine.front().c_str())));
00107                         tokenizedLine.pop_front();
00108                         
00109                         while (!tokenizedLine.empty())
00110                         {
00111                                 userMessage.data.push_back(atoi(tokenizedLine.front().c_str()));
00112                                 tokenizedLine.pop_front();
00113                         }
00114                         
00115                         // if required, sleep
00116                         if ((respectTimings) && (lastTimeStamp.value != 0))
00117                         {
00118                                 const UnifiedTime lostTime(UnifiedTime() - lastEventTime);
00119                                 const UnifiedTime deltaTimeStamp(timeStamp - lastTimeStamp);
00120                                 if (lostTime < deltaTimeStamp)
00121                                 {
00122                                         UnifiedTime waitTime(deltaTimeStamp - lostTime);
00123                                         waitTime /= speedFactor;
00124                                         waitTime.sleep();
00125                                 }
00126                         }
00127                         
00128                         // write message on all connected streams
00129                         for (StreamsSet::iterator it = dataStreams.begin(); it != dataStreams.end();++it)
00130                         {
00131                                 Stream* destStream(*it);
00132                                 if (destStream != in)
00133                                 {
00134                                         userMessage.serialize(destStream);
00135                                         destStream->flush();
00136                                 }
00137                         }
00138                         
00139                         lastEventTime = UnifiedTime();
00140                         lastTimeStamp = timeStamp;
00141                         
00142                         line.clear();
00143                 }
00144                 
00145         protected:
00146                 
00147                 void connectionCreated(Stream *stream)
00148                 {
00149                         //cerr << "got connection " << stream->getTargetName()  << endl;
00150                 }
00151                 
00152                 void incomingData(Stream *stream)
00153                 {
00154                         char c(stream->read<char>());
00155                         if (stream == in)
00156                         {
00157                                 if (c == '\n')
00158                                         sendLine();
00159                                 else
00160                                         line += c;
00161                         }
00162                 }
00163                 
00164                 void connectionClosed(Stream *stream, bool abnormal)
00165                 {
00166                         if (stream == in)
00167                                 stop();
00168                 }
00169         };
00170         
00172 }
00173 
00174 
00176 void dumpHelp(std::ostream &stream, const char *programName)
00177 {
00178         stream << "Aseba play, play recorded user messages from a file or stdin, usage:\n";
00179         stream << programName << " [options] [targets]*\n";
00180         stream << "Options:\n";
00181         stream << "--fast          : replay messages twice the speed of real time\n";
00182         stream << "--faster        : replay messages four times the speed of real time\n";
00183         stream << "--fastest       : replay messages as fast as possible\n";
00184         stream << "-f INPUT_FILE   : open INPUT_FILE instead of stdin\n";
00185         stream << "-h, --help      : shows this help\n";
00186         stream << "-V, --version   : shows the version number\n";
00187         stream << "Targets are any valid Dashel targets." << std::endl;
00188         stream << "Report bugs to: aseba-dev@gna.org" << std::endl;
00189 }
00190 
00192 void dumpVersion(std::ostream &stream)
00193 {
00194         stream << "Aseba play " << ASEBA_VERSION << std::endl;
00195         stream << "Aseba protocol " << ASEBA_PROTOCOL_VERSION << std::endl;
00196         stream << "Licence LGPLv3: GNU LGPL version 3 <http://www.gnu.org/licenses/lgpl.html>\n";
00197 }
00198 
00199 int main(int argc, char *argv[])
00200 {
00201         Dashel::initPlugins();
00202         bool respectTimings = true;
00203         int speedFactor = 1;
00204         std::vector<std::string> targets;
00205         const char* inputFile = 0;
00206         
00207         int argCounter = 1;
00208         
00209         while (argCounter < argc)
00210         {
00211                 const char *arg = argv[argCounter];
00212                 
00213                 if (strcmp(arg, "--fastest") == 0)
00214                 {
00215                         respectTimings = false;
00216                 }
00217                 else if (strcmp(arg, "--fast") == 0)
00218                 {
00219                         speedFactor = 2;
00220                 }
00221                 else if (strcmp(arg, "--faster") == 0)
00222                 {
00223                         speedFactor = 4;
00224                 }
00225                 else if ((strcmp(arg, "-h") == 0) || (strcmp(arg, "--help") == 0))
00226                 {
00227                         dumpHelp(std::cout, argv[0]);
00228                         return 0;
00229                 }
00230                 else if ((strcmp(arg, "-V") == 0) || (strcmp(arg, "--version") == 0))
00231                 {
00232                         dumpVersion(std::cout);
00233                         return 0;
00234                 }
00235                 else if (strcmp(arg, "-f") == 0)
00236                 {
00237                         argCounter++;
00238                         if (argCounter >= argc)
00239                         {
00240                                 dumpHelp(std::cout, argv[0]);
00241                                 return 1;
00242                         }
00243                         else
00244                                 inputFile = argv[argCounter];
00245                 }
00246                 else
00247                 {
00248                         targets.push_back(argv[argCounter]);
00249                 }
00250                 argCounter++;
00251         }
00252         
00253         if (targets.empty())
00254                 targets.push_back(ASEBA_DEFAULT_TARGET);
00255         
00256         try
00257         {
00258                 Aseba::Player player(inputFile, respectTimings, speedFactor);
00259                 for (size_t i = 0; i < targets.size(); i++)
00260                         player.connect(targets[i]);
00261                 player.run();
00262         }
00263         catch(Dashel::DashelException e)
00264         {
00265                 std::cerr << e.what() << std::endl;
00266         }
00267         
00268         return 0;
00269 }


aseba
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:16