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 }