#ifndef _BEHAVIOR_HH_ #define _BEHAVIOR_HH_ /* Author : Chuck Schied * Date : 2000-06-04 * Updated : 2000-10-19 (changed to pthreads from processes) * File : Behavior.hh * * Purpose and : This class provides the user with a Behavioral-style * Description : programming interface to use when writing code for a * : robot. It is meant to be a base class and all behaviors * : that are implemented with it are derived classes. The only * : method that the derived class needs to provide is the run () * : method. Thus, the implementation of a simple behavior might * : look something like this -> * * class RandomMovement : public Behavior * { * public: * RandomMovement (char* name, priority_t priority, * char* serverHostname, int serverPort) : * Behavior (name, priority, serverHostname, serverPort) * { * // not much to do in here ... * } * * private: * int run () // makes the robot move randomly * { * // set the translational, rotational and turret * // velocities to random numbers * vm (rand ()*20, rand ()*20, rand ()*20); * } * }; * * : Since this class is meant to be used in a threaded * : environment, the run method must be static. (Note that * : the only threading calls that a derived class will make are * : all hidden in this base class via the testSuspend () call. * : Hopefully this will make life easier on all of us.) This * : should not be a problem since there should only be one * : instance of a given derived behavior running on one machine * : at any given time. If this is not the case ... we're * : screwed. :P */ /********************** *** SYSTEM HEADERS *** **********************/ #include #include #include //#include //#include #include #include #include #include /********************* *** LOCAL HEADERS *** *********************/ #include "Common.hh" #include "Semaphore.hh" /********************** *** BEHAVIOR CLASS *** **********************/ /** * class Behavior: * Note that most of the methods in Behavior are static since they need * to get called from the static run () method, which in turn must be * static so that a pthread can get started with it as the controlling * function/method thingy. */ class Behavior //: public wxThread { public: /********************** *** PUBLIC METHODS *** **********************/ Behavior (char* name, priority_t priorityLevel, int levelID, char* serverHostname, int serverPort); // make a new behavior. happy, happy, joy, // joy virtual ~Behavior (); // cleanup and get the hell out static void* Entry (void* arg); // this method is the main entry point for // the behavior. It's main purpose is to // call run, although pretty much any other // sort of initialization stuff could be // done in it (I think that network initing // is, but I'm too lazy to open up the .cc // file). protected: /************************* *** PROTECTED METHODS *** *************************/ void Pause (); void Resume (); virtual int run(); // the method that this behavior runs - // must be overridden by a derived // class in order to do anything useful bool testSuspend (); // this method is the one that is used by // a derived behavior to see if it should // suspend itself (although the actual // suspension will get done in this method // without any intervention by the actual // derived behavior) and this method will // return true if it got suspended and false // otherwise. virtual void onSuspend (); // this method will get called immediately // before a Behavior is suspended. Things // such as stopping motion should be done in // this method. virtual void onResume (); // this method will get called immediately // after a Behavior is resumed. The current // state of the robot should be examined, // etc. in this method. int sendCommand (command_t command); // this method simply sends the appropriate // command to the BehaviorManager. Herein // lies the beauty of this implementation. void initializeNetworking (); // who really wants to know about AF_INET and // other crap like that? I wish I got an // initializeSelf () call that I could use in // the morning ... showered and shaved in // 10.423 nanoseconds. void registerWithServer (); // yet again ... if only life was this easy. /********************** *** PROTECTED DATA *** **********************/ char* name; // the name of this behavior - to be given // at its baptism 8 days after it is born // (unless, of course, it is Hindu, Muslim, // Athiest, etc. cause I'm not sure how those // religions work. Come to think of it, a // robot behavior probably doesn't need a // religious affiliation.) priority_t priorityLevel; // this behavior's position in the food chain int levelID; // this behavior's id within its priority // group - this probably isn't neccessary, but // I'd much rather code it in now and not use // it ... char* serverHostname; // who's your mommy (or daddy)? int serverPort; // gotta talk on a port - why not this one? int clientPort; // and listen on a different one int server; // file descriptor to write to the server int clientSocket; // file descriptor to accept connections from // the server int clientServer; Semaphore* sem; /****************************** *** NETWORKING MUMBO-JUMBO *** ******************************/ struct sockaddr_in ServerAddress; struct sockaddr_in ClientAddress, ClientServerAddress; // if only these were actually socks ... maybe // my feet would be warmer since it's so damn // cold in this room ... socklen_t ServerAddressLength, ClientAddressLength, ClientServerAddressLength; struct hostent *hostEntry; // who'd have ever guessed that you'd need // to allocate memory for this pointer? =P }; #endif /* _BEHAVIOR_HH_ */