Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

simpleComm.cpp

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////
00002 /*! \file simpleComm.cpp
00003  *  \brief This file provides an example of comm functionality.
00004  *  \author  $Author: rsharo $
00005  *  \version $Revision: 1.4 $
00006  *  \date    $Date: 2004/04/07 13:49:27 $
00007  *//////////////////////////////////////////////////////////////////////////////
00008 
00009 #include "Whorl.h"
00010 #include "WhorlSim.h"
00011 #include "CfgParse.h"
00012 #include "Measurement.h"
00013 #include <iostream>
00014 #include <sstream>
00015 
00016 #include "ace/ACE.h"
00017 #include "ace/Log_Msg.h"
00018 #include "Utils/SystemProperties.h"
00019 #include "Comm/CommFactory.h"
00020 #include "Comm/MessageClient.h"
00021 #include "Comm/MessageServer.h"
00022 
00023 using namespace std;
00024 
00025 
00026 
00027 //
00028 // This class represents a client that generates
00029 // Rate gyro readings.  For simplicity of this example, the messages are
00030 // in the form of ASCII strings that the main() generates.
00031 class RG_Writer : public MessageClient
00032 {
00033 public:
00034         //
00035         // This allows us to define the message ID for this client
00036         // right here in the class declaration.
00037         enum { MY_MSG_ID = 101 };
00038 
00039         //
00040         // The constructor establishes this client's ID field.
00041         // Messages with this ID will be read by this client.
00042         // We're also registering with the Comm system right out 
00043         // of the constructor for this example.
00044         RG_Writer(MessageServer *pMsgSvr) : MessageClient(MY_MSG_ID)
00045                  { Register(pMsgSvr); }
00046 
00047         //
00048         // This method is here to allow external code (like main())
00049         // to send messages as if they came from this client.
00050         // This method assumes the message is a null-terminated ASCII string.
00051         int SendMessage(const char *msg, u_int dest)
00052         {
00053                 ACE_DEBUG((LM_DEBUG,
00054                          "Sending this message to the reader: %s\n", msg));
00055 
00056                 return MessageClient::SendMessage(msg, strlen(msg)+1, dest);
00057         }
00058 
00059         //
00060         // All clients must implement this method.  This is the one that
00061         // is called when a message is routed to this client.
00062         // If this method ever returns -1, then the client is disconncted
00063         // and won't receive any more messages. This is a good idea
00064         // when the client has outlived its usefulness.
00065         // Clients can be reconnected later with another call to Register().
00066         int ReceiveMessage(const char *msg, size_t len)
00067         {
00068                 // This client just prints the message it got.
00069                 ACE_DEBUG((LM_DEBUG, "Writer got a message: %s\n", msg));
00070 
00071                 return 0;
00072         }
00073 };
00074 
00075 
00076 
00077 
00078 //
00079 // This class represents a client that generates
00080 // Rate gyro readings.  For simplicity of this example, the messages are
00081 // in the form of ASCII strings that the main() generates.
00082 class RG_Reader : public MessageClient
00083 {
00084 public:
00085         //
00086         // This allows us to define the message ID for this client
00087         // right here in the class declaration.
00088         enum { MY_MSG_ID = 100 };
00089 
00090         //
00091         // The constructor establishes this client's ID field.
00092         // Messages with this ID will be read by this client.
00093         // We're also registering with the Comm system right out 
00094         // of the constructor for this example.
00095         RG_Reader(MessageServer *pMsgSvr) : MessageClient(MY_MSG_ID)
00096                  { Register(pMsgSvr); }
00097 
00098         //
00099         // All clients must implement this method.  This is the one that
00100         // is called when a message is routed to this client.
00101         // If this method ever returns -1, then the client is disconncted
00102         // and won't receive any more messages. This is a good idea
00103         // when the client has outlived its usefulness.
00104         // Clients can be reconnected later with another call to Register().
00105         //
00106         // This method parses the string and extracts the rate gyro
00107         // measurements. It then prints the measurements on the console.
00108         //
00109         // Finally, it sends the message 'OK' back to the writer so it
00110         // knows its message was received.
00111         int ReceiveMessage(const char *msg, size_t len)
00112         {
00113                 ACE_DEBUG((LM_DEBUG, "Reader got a message: %s\n", msg));
00114 
00115                 istringstream iss(msg);
00116 
00117                 double rg[3];
00118 
00119                 iss >> rg[0] >> rg[1] >> rg[2];
00120 
00121                 ACE_DEBUG((LM_DEBUG, "   Rate gyro readings: %f %f %f\n",
00122                                          rg[0], rg[1], rg[2]));
00123 
00124                 ACE_DEBUG((LM_DEBUG, "Sending the reply message 'OK' to the writer.\n"));
00125 
00126                 this->SendMessage("OK", 3, RG_Writer::MY_MSG_ID);
00127 
00128                 return 0;
00129         }
00130 };
00131 
00132 
00133 
00134 int main() {
00135 
00136         //
00137         // Disable purely informational log messages. The just clutter
00138         // the console.
00139         {
00140                 u_long mask = 
00141                         ACE_Log_Msg::instance()->priority_mask(ACE_Log_Msg::PROCESS);
00142 
00143                 ACE_Log_Msg::instance()->priority_mask(mask & ~LM_INFO,
00144                          ACE_Log_Msg::PROCESS);
00145         }
00146 
00147 
00148         cout << "Code is running." << endl;
00149 
00150         //
00151         // Load the system configuration from an INI-style
00152         // config file.
00153         SystemProperties *props = SystemProperties::Instance("System.config");
00154 
00155         //
00156         // All you need to do to set up comm is construct a factory
00157         // and tell it to open. Then all the clients can use
00158         // the factory to connect to the network.
00159         PropertyBasedCommFactory commFact;
00160 
00161         //
00162         // This tells the factory to get its properties from the
00163         // section of the config file labeled "Typhon\Comm".
00164         if (commFact.Open(*props, "Typhon\\Comm") == -1)
00165         {
00166                 ACE_ERROR_RETURN((LM_ERROR, "Comm setup failed.\n"), -1);
00167         }
00168 
00169         //
00170         // Get the message server from our factory. We use this to connect
00171         // our clients to the network.
00172         MessageServer *pMsgSvr = commFact.GetMessageServer();
00173 
00174         //
00175         // Construct a client that will be sending rate gyro messages
00176         // over the network.
00177         RG_Writer myWriter(pMsgSvr);
00178 
00179         //
00180         // Construct a client that will be reading rate gyro messages
00181         // from the network.
00182         RG_Reader myReader(pMsgSvr);
00183 
00184         
00185         /** Prepare for parsing */
00186         cfgBody *cfgDat;
00187         CfgParse parser;
00188         
00189         /** Parse out configuration files */
00190         cout << "Parsing Whorl configuration file." << endl;
00191         cfgDat = parser.go("simpleComm.cfg");
00192 
00193         Whorl whorlOne;
00194         whorlOne.Initialize(cfgDat);
00195   
00196         timeval t;
00197         whorlOne.GetRateGyro(string("dmu_rg1"))->GetMeasurement().GetTime(t);
00198         whorlOne.SetTimeOfEstimate(t);  // it doesn't make sense to set time in the config file!
00199 
00200 
00201         Measurement rateGyroMeasurements[3];
00202         Vector rateGyroDoubles(3);
00203         
00204         cout << "Entering the loop." << endl;
00205 
00206         ACE_OS::sleep(5);
00207 
00208         for ( int ii = 1; ii <= 100; ii++ ) {
00209                 
00210                 //
00211                 // Get the measurement from the rate gyros
00212                 rateGyroMeasurements[0] =
00213                          whorlOne.GetRateGyro(string("dmu_rg1"))->GetMeasurement();
00214                 rateGyroMeasurements[1] =
00215                          whorlOne.GetRateGyro(string("dmu_rg2"))->GetMeasurement();
00216                 rateGyroMeasurements[2] =
00217                          whorlOne.GetRateGyro(string("dmu_rg3"))->GetMeasurement();
00218         
00219 
00220                 //
00221                 // Use the ostringstream class to build a message
00222                 // in the form of an ASCII string...
00223                 ostringstream oss;
00224                 oss << rateGyroMeasurements[0].GetAsDouble() << " "
00225                         << rateGyroMeasurements[1].GetAsDouble() << " "
00226                         << rateGyroMeasurements[2].GetAsDouble();
00227 
00228                 //
00229                 // Convert the ostringstream into a C++ string,
00230                 // and then convert that C++ string into a C string.
00231                 const char *msg = oss.str().c_str();
00232 
00233                 //
00234                 // Send the string out to everyone who wants it.
00235                 if (myWriter.SendMessage(msg, RG_Reader::MY_MSG_ID) == -1)
00236                 {
00237                         ACE_ERROR_RETURN((LM_ERROR,
00238                                 "***Sending a message failed. Aborting.\n"), -1);
00239                 }
00240 
00241                 cout << " Sent." << endl;
00242                 
00243         };
00244 
00245         
00246         cout << "Out of the loop." << endl;
00247 
00248         //
00249         // Give the clients time to process all the messages.
00250         ACE_OS::sleep(3);
00251         
00252                 
00253         return 0;
00254         
00255 };
00256 
00257 
00258 
00259 // Do not change the comments below - they will be added automatically by CVS
00260 /*****************************************************************************
00261 *       $Log: simpleComm.cpp,v $
00262 *       Revision 1.4  2004/04/07 13:49:27  rsharo
00263 *       Completely redone to demonstrate the MessageServer/MessageClient comm scheme.
00264 *       System.config is now an INI-style configuration file.
00265 *
00266 *       Revision 1.3  2003/12/17 22:42:31  rsharo
00267 *       Addes more comments.
00268 *
00269 *       Revision 1.2  2003/12/17 21:00:37  rsharo
00270 *       Added communication code.
00271 *
00272 *       Revision 1.1  2003/12/08 13:54:51  simpliciter
00273 *       First cut of sample Comm files.
00274 *
00275 *       
00276 *
00277 ******************************************************************************/
00278 
00279 
00280 
00281 

Generated on Wed Sep 5 12:54:25 2007 for DSACSS Operational Code by  doxygen 1.3.9.1