ALMA Computing Group

acsexmplAsyncCalls.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * ALMA - Atacama Large Millimiter Array
00003 * (c) European Southern Observatory, 2004
00004 *
00005 *This library is free software; you can redistribute it and/or
00006 *modify it under the terms of the GNU Lesser General Public
00007 *License as published by the Free Software Foundation; either
00008 *version 2.1 of the License, or (at your option) any later version.
00009 *
00010 *This library is distributed in the hope that it will be useful,
00011 *but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 *Lesser General Public License for more details.
00014 *
00015 *You should have received a copy of the GNU Lesser General Public
00016 *License along with this library; if not, write to the Free Software
00017 *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00018 *
00019 * "@(#) $Id: acsexmplAsyncCalls.cpp,v 1.8 2008/07/10 10:00:37 bjeram Exp $"
00020 *
00021 * who       when      what
00022 * --------  --------  ----------------------------------------------
00023 * acaproni  2004-08-09  created
00024 */
00025 
00034 
00039 
00062 /* @}*/
00063 /* @}*/
00064 
00065 #include <maciSimpleClient.h>
00066 #include <baciThread.h>
00067 #include "acsexmplMountC.h"
00068 #include "acsexmplAsyncCallbacks.h"
00069 #include "acsexmplAsyncMethodCB.h"
00070 #include <iostream>
00071 #include <string>
00072 
00073 static char *rcsId="@(#) $Id: acsexmplAsyncCalls.cpp,v 1.8 2008/07/10 10:00:37 bjeram Exp $";
00074 static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);
00075 
00076 using namespace maci;
00077 using namespace baci;
00078 
00079 typedef struct threadParamStruct {
00080         MOUNT_ACS::Mount* mount;
00081         double az;
00082         double el;
00083 } ThreadParamStruct;
00084 
00090 static void
00091 worker(void *threadParam_p) {
00092 
00093         if (threadParam_p==NULL) {
00094                 ACS_SHORT_LOG((LM_ERROR,"Invalid parameter for thread!"));
00095                 return;
00096         }
00097 
00098         //Get access to the BACI thread this function is being executed from
00099     BACIThreadParameter *baciParameter_p = static_cast<BACIThreadParameter *>(threadParam_p);
00100     BACIThread *myself_p = baciParameter_p->getBACIThread();
00101 
00102         // Init the thread
00103     if (BACIThread::InitThread != 0)  {
00104                 BACIThread::InitThread("Position thread");
00105         }
00106 
00107     ACS_SHORT_LOG((LM_INFO,"Thread started with name %s",myself_p->getName().c_str()));
00108 
00109     // Get the struct from the parameter
00110     ThreadParamStruct* param=(ThreadParamStruct*)baciParameter_p->getParameter();
00111 
00112     // Get the reference to the actAz property of the mount
00113     ACS::ROdouble_var actAz = param->mount->actAz();
00114     if (CORBA::is_nil(actAz)) {
00115         ACS_SHORT_LOG((LM_ERROR,"ERROR getting actAz"));
00116         return;
00117     }
00118 
00119     // Get the reference to the actEl property of the mount
00120     ACS::ROdouble_var actEl = param->mount->actEl();
00121     if (CORBA::is_nil(actEl)) {
00122         ACS_SHORT_LOG((LM_ERROR,"ERROR getting actEl"));
00123         return;
00124     }
00125 
00126     // The az (azimuth) and el (elevation) are declared here
00127     // but they are both updated in the callback
00128         double az,el;
00129         ACSErr::Completion_var completion;
00130 
00131         // Create the structs for the async calls to read the values of az
00132         AsyncCBdouble azCallback("actAz",&az);
00133         ACS::CBdouble_var actAz_CB = azCallback._this();
00134         ACS::CBDescIn actAzDescIn;
00135         // Create the structs for the async calls to read the values of az
00136         AsyncCBdouble elCallback("actEl",&el);
00137         ACS::CBdouble_var actEl_CB = elCallback._this();
00138         ACS::CBDescIn actElDescIn;
00139 
00140         // Create the callback for the objfix method
00141         AsyncMethodCBvoid objfixCB("objfix");
00142         ACS::CBvoid_var objfix_CB = objfixCB._this();
00143         ACS::CBDescIn objfixDescIn;
00144 
00145         // Times handshaking is not yet implemented so
00146         // we do not really need to fill these fields
00147         //objfixDescIn.normal_timeout=10000000;
00148         //objfixDescIn.negotiable_timeout=5000000;
00149 
00150         CORBA::Double newAz=(CORBA::Double)param->az;
00151         CORBA::Double newEl=(CORBA::Double)param->el;
00152 
00153         ACS_SHORT_LOG((LM_INFO,"Calling the asynchronous objfix"))
00154 
00155         param->mount->objfix(newAz,newEl,objfix_CB.in(),objfixDescIn);
00156 
00157         while(myself_p->check() == true) {
00158 
00159                 if(myself_p->isSuspended() == false) {
00160                         ACS_SHORT_LOG((LM_INFO,"Calling the async methods to read Az and El"))
00161                         actAz->get_async(actAz_CB.in(),actAzDescIn);
00162                         actEl->get_async(actEl_CB.in(),actElDescIn);
00163                 } else {
00164                         myself_p->sleep();
00165                 }
00166 
00167                 sleep(1);
00168         }
00169 
00170         ACS_SHORT_LOG((LM_INFO,"Exiting thread"))
00171         sleep(5);
00172         if (BACIThread::DoneThread != 0) {
00173                 BACIThread::DoneThread();
00174         }
00175 
00176     delete baciParameter_p;
00177     myself_p->setStopped();
00178 }
00179 
00182 int main(int argc, char* argv[])
00183 {
00184     MOUNT_ACS::Mount_var mount;
00185     BACIThreadManager threadManager;   // The thread manager is used to manage the thread
00186     ThreadParamStruct param; // The parameter for the thread
00187 
00188     // Check the arguments in the command line
00189         if (argc<2) {
00190                 std::cerr<<"Usage: "<<argv[0]<<" component azimuth elevation <options>\n";
00191                 return -1;
00192         }
00193 
00194         double destAz, destEl;
00195         if (sscanf(argv[2],"%lf",&destAz)+sscanf(argv[3],"%lf",&destEl)!=2) {
00196                 std::cerr<<"Format error in azimuth and/or elevation"<<std::endl;
00197                 std::cerr<<"Usage: "<<argv[0]<<" component azimuth elevation <options>\n";
00198                 return -1;
00199         }
00200 
00201         // Create the SimpleClient object
00202         SimpleClient mountClient;
00203 
00204         // Init the client
00205         if (mountClient.init(argc,argv)==0) {
00206                 // Error initing
00207                 ACS_SHORT_LOG((LM_ERROR,"Error initing the client"));
00208                 return -1;
00209         } else {
00210                 ACS_SHORT_LOG((LM_INFO,"SimpleClient built"));
00211         }
00212 
00213         // Login the client
00214         if (mountClient.login()==0) {
00215                 //Error
00216                 ACS_SHORT_LOG((LM_ERROR,"Error logging in the client"));
00217                 return -1;
00218         } else {
00219                 ACS_SHORT_LOG((LM_INFO,"Client logged in"));
00220         }
00221 
00222         try
00223             {
00224             // Get the component
00225             ACS_SHORT_LOG((LM_INFO,"Getting component %s",argv[1]));
00226             mount = mountClient.getComponent<MOUNT_ACS::Mount>(argv[1], 0, true);
00227             }
00228         catch(maciErrType::CannotGetComponentExImpl &_ex)
00229             {
00230             _ex.log();
00231             return -1;
00232             }
00233 
00234         param.mount=mount.ptr();
00235         param.az=destAz;
00236         param.el=destEl;
00237 
00238         char logStr[128];
00239         sprintf(logStr,"Commanded position az=%lf, el=%lf",destAz,destEl);
00240         ACS_SHORT_LOG((LM_INFO,logStr));
00241 
00242         // Start the thread to read the position of the antenna
00243         ACS_SHORT_LOG((LM_INFO,"Starting the thread"));
00244         BACIThread* thread_p = threadManager.create("Position thread",    //Name of the new thread
00245                 (void *)worker,    //Function to run inside the thread
00246                 static_cast<void *>(&param));    //the single parameter
00247 
00248         if (thread_p==NULL)  {
00249                 ACS_SHORT_LOG((LM_ERROR,"Error in spawning thread"));
00250         }
00251         thread_p->resume();
00252 
00253         // The thread will run for 30 secs so we wait until it finishes
00254         // There are better (and safer) solution to wait instead of a simple wait
00255         // but... this is the faster one!
00256         sleep(40);
00257 
00258         // End of computation: begin to clean up
00259 
00260         // Stop all the threads
00261         ACS_SHORT_LOG((LM_INFO,"Terminating the thread"));
00262         threadManager.terminateAll();
00263 
00264         // Release the component
00265         try
00266             {
00267             ACS_SHORT_LOG((LM_INFO,"Releasing %s",argv[1]));
00268             mountClient.releaseComponent(argv[1]);
00269             }
00270         catch(maciErrType::CannotReleaseComponentExImpl &_ex)
00271             {
00272             _ex.log();
00273             return -1;
00274             }
00275 
00276         // logout the client
00277         try
00278             {
00279             ACS_SHORT_LOG((LM_INFO,"Logging out"));
00280             mountClient.logout();
00281             }
00282         catch (...)
00283             {
00284             ACS_SHORT_LOG((LM_ERROR,"Error logging out the simple client object"));
00285             ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__,
00286                                                             "main");
00287             uex.log();
00288             return -1;
00289             }//try-catch
00290 
00291         ACS_SHORT_LOG((LM_INFO,"Done"));
00292 
00293         return 0;
00294 }