ALMA Computing Group

acsexmplFilterWheelImpl.cpp

Go to the documentation of this file.
00001 /******************************************************************************* 00002 * ALMA - Atacama Large Millimiter Array 00003 * (c) European Southern Observatory, 2002 00004 * Copyright by ESO (in the framework of the ALMA collaboration) 00005 * and Cosylab 2002, All rights reserved 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library 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 GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * 00022 * 00023 * "@(#) $Id: acsexmplFilterWheelImpl.cpp,v 1.12 2008/10/09 08:41:11 cparedes Exp $" 00024 * 00025 * who when what 00026 * -------- -------- ---------------------------------------------- 00027 * acaproni 2004-04-26 Creation 00028 */ 00029 00030 #include <string> 00031 00032 #include <baciDB.h> 00033 #include <maciContainerServices.h> 00034 #include <acsexmplFilterWheelImpl.h> 00035 #include <cdbDALC.h> 00036 00037 using namespace std; 00038 00042 const static int MOVEFILTER_ACTION = 0; 00043 const static int MOVESLOT_ACTION = 1; 00044 const static int ADJUST_ACTION = 2; 00045 00046 ACE_RCSID(acsexmpl, acsexmplFilterWheelImpl, "$Id: acsexmplFilterWheelImpl.cpp,v 1.12 2008/10/09 08:41:11 cparedes Exp $") 00047 00048 using namespace baci; 00049 00051 // FilterWheel 00053 00054 FilterWheel::FilterWheel(const ACE_CString &name,maci::ContainerServices* containerServices) : 00055 CharacteristicComponentImpl(name,containerServices), 00056 m_position_sp(this), 00057 m_desc_sp(new ROstring(name+":desc", getComponent()),this), 00058 m_slots_sp(this), m_wheelConfiguration(0) 00059 { 00060 // Build the full name of the component 00061 m_fullName="alma/"+name; 00062 00063 ACS_TRACE("::FilterWheel::FilterWheel"); 00064 00065 } 00066 00067 FilterWheel::~FilterWheel() 00068 { 00069 ACS_TRACE("::FilterWheel::~FilterWheel"); 00070 } 00071 /* --------------------- [ CDB related methods ] ---------------------*/ 00072 void FilterWheel::readConfiguration(Descriptor* descr) 00073 { 00074 if (descr==NULL) { 00075 ACS_SHORT_LOG((LM_ERROR,"FilterWheel::readConfiguration Uninitialized variable m_wheelConfiguration!")); 00076 return; 00077 } 00078 00079 // Get the number of available slots in the wheel from 00080 // the property m_slots_sp 00081 // NOTE: this is also the length of the array of slots 00082 ACSErr::Completion_var completion; 00083 unsigned int availableSlots = (unsigned int)m_slots_sp->get_sync(completion); 00084 00085 // Get the DAl from the container services 00086 CDB::DAL_ptr dal_p = getContainerServices()->getCDB(); 00087 // Get tha DAo record for the component 00088 CDB::DAO_ptr dao_p = dal_p->get_DAO_Servant(m_fullName.c_str()); 00089 00090 00091 // Read the sequence of long describing the position of each slot 00092 // in the wheel 00093 CDB::longSeq* lngSeq =dao_p->get_long_seq("SlotStep"); 00094 00095 // Check if the sequence of long is valid 00096 if (lngSeq==NULL) { 00097 ACS_SHORT_LOG((LM_ERROR,"No slots found in %s",m_fullName.c_str())); 00098 return; 00099 } 00100 00101 // Check if the user defined all the slots 00102 if (lngSeq->length()!=availableSlots) { 00103 ACS_SHORT_LOG((LM_WARNING,"Availbale and defined slots disagree in CDB")); 00104 } 00105 00106 for (CORBA::ULong t=0; t<lngSeq->length() && t<availableSlots; t++) 00107 { 00108 descr[t].step=(*lngSeq)[t]; 00109 } 00110 00111 // Read the keys of the filters 00112 // The key is the value of the first parameter in the CBD 00113 // For example in <_ Name="Red" Delta=..../> the key is Red. 00114 CDB::stringSeq* fltKeys = dao_p->get_string_seq("Filter"); 00115 00116 // Check if the sequence of keys is valid 00117 if (fltKeys==NULL) { 00118 ACS_SHORT_LOG((LM_ERROR,"No slots found in %s",m_fullName.c_str())); 00119 return; 00120 } 00121 // Read each filter definition and fill the wheel descriptor 00122 for (CORBA::ULong t=0; t<fltKeys->length() && t<availableSlots; t++) 00123 { 00124 char key[64]; 00125 char deltaName[128]; 00126 char slotName[128]; 00127 strcpy(key,((*fltKeys)[t])); 00128 // Define the name of the items to read 00129 // It is based on the name of the main tag (Filter) and the key 00130 // of the record (es. Red) plus the name of the item to read 00131 // (Delta or Slot in this example) 00132 sprintf(deltaName,"Filter/%s/Delta",key); 00133 sprintf(slotName,"Filter/%s/Slot",key); 00134 // Read the values from the CDB 00135 int delta = dao_p->get_long(deltaName); 00136 int slot = dao_p->get_long(slotName); 00137 // Store the name and the delta in the right slot 00138 if (slot>=0 && slot<(int)availableSlots) { 00139 descr[slot].delta=delta; 00140 strcpy(descr[slot].filterName,key); 00141 } else { 00142 ACS_SHORT_LOG((LM_ERROR,"The slot %d is invalid",slot)); 00143 } 00144 } 00145 00146 for (unsigned int k=0; k<availableSlots; k++) 00147 { 00148 std::cout<<k<<"> step="<<descr[k].step<<", delta="<<descr[k].delta; 00149 std::cout<<", filter=["<<descr[k].filterName<<"]\n"; 00150 } 00151 } 00152 00153 void FilterWheel::updateFilter(ACE_CString name, int delta) 00154 { 00155 ACS_SHORT_LOG((LM_INFO,"Updating the CDB entry for the %s filter setting delta to %d", 00156 name.c_str(), delta)); 00157 // Get the DAl from the container services 00158 CDB::DAL_ptr dal_p = getContainerServices()->getCDB(); 00159 // Get tha DAO record for the component 00160 //CDB::DAO_ptr dao_p = dal_p->get_DAO_Servant(m_fullName.c_str()); 00161 00162 CDB::WDAL_ptr wdal_p = CDB::WDAL::_narrow(dal_p); 00163 CDB::WDAO_ptr wdao_p = wdal_p->get_WDAO_Servant(m_fullName.c_str()); 00164 00165 00166 // Update the entry on the CDB 00167 // We need to build the key as we did to red the values 00168 ACE_CString deltaStr("Filter/"); 00169 deltaStr+=name; 00170 deltaStr+="/Delta"; 00171 00172 wdao_p->set_long(deltaStr.c_str(),delta); 00173 } 00174 00175 void FilterWheel::updateWheel(int slot, int step) 00176 { 00177 ACS_SHORT_LOG((LM_INFO,"Updating the position of slot %d to %d",slot,step)); 00178 00179 // Get the DAl from the container services 00180 CDB::DAL_ptr dal_p = getContainerServices()->getCDB(); 00181 // Get tha DAO record for the component 00182 //CDB::DAO_ptr dao_p = dal_p->get_DAO_Servant(m_fullName.c_str()); 00183 00184 CDB::WDAL_ptr wdal_p = CDB::WDAL::_narrow(dal_p); 00185 CDB::WDAO_ptr wdao_p = wdal_p->get_WDAO_Servant(m_fullName.c_str()); 00186 00187 // Read the sequence of long describing the position of each slot 00188 // in the wheel from the CDB 00189 CDB::longSeq* lngSeq =wdao_p->get_long_seq("SlotStep"); 00190 00191 // Check if the sequence of long is valid 00192 if (lngSeq==NULL) { 00193 ACS_SHORT_LOG((LM_ERROR,"No slots found in %s",m_fullName.c_str())); 00194 return; 00195 } 00196 00197 // Update the slot in the sequence 00198 (*lngSeq)[(CORBA::ULong)slot]=step; 00199 00200 for (CORBA::ULong t=0; t<lngSeq->length(); t++) 00201 { 00202 std::cout<<t<<". "<<(*lngSeq)[t]<<"\n"; 00203 } 00204 00205 // Update the entry in the CDB 00206 wdao_p->set_long_seq("SlotStep", *lngSeq); 00207 } 00208 00209 /* --------------------- [ Support methods ] -------------------- */ 00210 00211 00212 /* --------------------- [ Life cycle methods ] -------------------- */ 00213 00214 void FilterWheel::initialize() 00215 { 00216 ACS_TRACE("::FilterWheel::initialize"); 00217 00218 m_position_sp=new ROdouble(getContainerServices()->getName()+":position", getComponent()); 00219 // Position is 0 at the beginning 00220 ACS::Time timestamp; 00221 m_position_sp->getDevIO()->write(0.0, timestamp); 00222 00223 // There are two ways to get an attribute of the component 00224 // 1. from the DAO of the component 00225 // (shown for the FilterWheel attribute) 00226 // 2. using the get_characteristic method 00227 // (shown for the AvailableSlots attribute) 00228 // We'll show boths 00229 00230 // 1 00231 // Get the description of this filter wheel from the xml file 00232 // It is an attribute of the component 00233 CDB::DAL_ptr dal_p = getContainerServices()->getCDB(); 00234 //DAOImpl* dao_p = new DAOImpl(dal_p->get_DAO(m_fullName.c_str())); 00235 CDB::DAO_ptr dao_p = dal_p->get_DAO_Servant(m_fullName.c_str()); 00236 char* descr=NULL; 00237 try 00238 { 00239 descr = dao_p->get_string("FilterWheelDescription"); 00240 if (descr!=NULL) 00241 { 00242 ACS_SHORT_LOG((LM_INFO,"FilterWheel Description is %s",descr)); 00243 } 00244 else 00245 { 00246 ACS_SHORT_LOG((LM_ERROR,"Descr is NULL!")); 00247 } 00248 } 00249 catch (...) 00250 { 00251 // We receive an error from the CDB 00252 // maybe a WrongDataType or a FieldDoesNotExist exception 00253 descr=NULL; 00254 ACS_SHORT_LOG((LM_ERROR,"Error reading FilterWheel Description from the CDB")); 00255 } 00256 if (descr!=NULL) 00257 { 00258 m_desc_sp->getDevIO()->write(descr, timestamp); 00259 } 00260 00261 // 2 00262 // Get the number of available slots from the CDB 00263 // It is an attribute of the component 00264 m_slots_sp=new ROlong(getContainerServices()->getName()+":slots", getComponent()); 00265 long availSlots; 00266 try 00267 { 00268 CORBA::Any* characteristic = get_characteristic_by_name("AvailableSlots"); 00269 const char* val; 00270 if (!(*characteristic>>=val)) 00271 { 00272 ACS_SHORT_LOG((LM_ERROR,"Error getting AvailableSlots value by the CORBA::Any object")); 00273 } 00274 else 00275 { 00276 // Convert the string 00277 availSlots=atoi(val); 00278 m_slots_sp->getDevIO()->write(availSlots, timestamp); 00279 } 00280 } 00281 catch (...) 00282 { 00283 // An error occurred reading the characteristic 00284 // This method throws ACS::NoSuchCharacteristic 00285 ACS_SHORT_LOG((LM_ERROR,"Error reading the characteristic AvailableSlots by its name")); 00286 return; 00287 } 00288 00289 // Build the array of descriptors 00290 if (availSlots>0) { 00291 m_wheelConfiguration = new Descriptor[availSlots]; 00292 // Fill each item with default values 00293 for (int t=0; t<availSlots; t++) { 00294 m_wheelConfiguration[t].step=0; 00295 m_wheelConfiguration[t].delta=0; 00296 m_wheelConfiguration[t].filterName[0]=0; 00297 } 00298 } 00299 } 00300 00301 void FilterWheel::execute() 00302 { 00303 ACS_TRACE("::FilterWheel::execute"); 00304 00305 // Read the CDb to build the actual configuration of the wheel 00306 readConfiguration(m_wheelConfiguration); 00307 } 00308 00309 void FilterWheel::cleanUp() 00310 { 00311 // Free the array 00312 delete[] m_wheelConfiguration; 00313 00314 } 00315 00316 void FilterWheel::aboutToAbort() 00317 { 00318 } 00319 00320 /* --------------- [ Action implementator interface ] -------------- */ 00321 00322 ActionRequest 00323 FilterWheel::invokeAction (int function, 00324 BACIComponent *cob_p, 00325 const int &callbackID, 00326 const CBDescIn &descIn, 00327 BACIValue *value_p, 00328 Completion &completion, 00329 CBDescOut &descOut) 00330 { 00331 ACS_SHORT_LOG((LM_INFO,"FilterWheel::invokeAction")); 00332 00333 // better implementation with array is possible 00334 switch (function) 00335 { 00336 case MOVEFILTER_ACTION: 00337 { 00338 return moveFilterAction(cob_p, callbackID, descIn, value_p, completion, descOut); 00339 } 00340 case MOVESLOT_ACTION: 00341 { 00342 return moveSlotAction(cob_p, callbackID, descIn, value_p, completion, descOut); 00343 } 00344 case ADJUST_ACTION: 00345 { 00346 return adjustAction(cob_p, callbackID, descIn, value_p, completion, descOut); 00347 } 00348 default: 00349 { 00350 ACS_SHORT_LOG((LM_WARNING,"Unimplemented action requested: %d is unknon",function)); 00351 return reqDestroy; 00352 } 00353 } 00354 } 00355 00356 /* ------------------ [ Action implementations ] ----------------- */ 00357 00359 ActionRequest 00360 FilterWheel::adjustAction ( 00361 BACIComponent *cob_p, 00362 const int &callbackID, 00363 const CBDescIn &descIn, 00364 BACIValue *value_p, 00365 Completion &completion, 00366 CBDescOut &descOut) 00367 { 00368 ACS_SHORT_LOG((LM_INFO,"::FilterWheel::adjustAction", "%s", getComponent()->getName())); 00369 00370 int* steps = static_cast<int*>(const_cast<void *>(value_p->pointerValue())); 00371 00372 ACS::Time timestamp; 00373 ACSErr::Completion_var compl; 00374 00375 int newPosition=(int)m_position_sp->get_sync(compl)+*steps; 00376 m_position_sp->getDevIO()->write(newPosition, timestamp); 00377 ACS_SHORT_LOG((LM_INFO,"Wheel rotaed to step %d",newPosition)); 00378 00379 DBConnector::writeCommand(getComponent()->getName(), "move", getStringifiedTimeStamp()); 00380 00381 completion = ACSErrTypeOK::ACSErrOKCompletion(); 00382 00383 // if OK action will be destroyed and we do not need it anymore 00384 if (steps!=0) 00385 { 00386 delete steps; 00387 steps=0; 00388 } 00389 00390 // complete action requesting done invocation, 00391 // otherwise return reqInvokeWorking and set descOut.estimated_timeout 00392 return reqInvokeDone; 00393 } 00394 00396 ActionRequest 00397 FilterWheel::moveFilterAction ( 00398 BACIComponent *cob_p, 00399 const int &callbackID, 00400 const CBDescIn &descIn, 00401 BACIValue *value_p, 00402 Completion &completion, 00403 CBDescOut &descOut) 00404 { 00405 ACS_SHORT_LOG((LM_INFO,"::FilterWheel::moveFilterAction", "%s", getComponent()->getName())); 00406 00407 ACE_CString* name = static_cast<ACE_CString*>(const_cast<void *>(value_p->pointerValue())); 00408 00409 ACSErr::Completion_var tempCompletion; 00410 unsigned int availableSlots = (unsigned int)m_slots_sp->get_sync(tempCompletion); 00411 00412 // The user wish to move the wheel to a defined filter. 00413 // We look for the slot that contains the filters to get its step 00414 // its adjustment (step) 00415 bool found=false; 00416 unsigned int t=0; 00417 for (; t<availableSlots; t++) { 00418 if (strcmp(name->c_str(),m_wheelConfiguration[t].filterName)==0) { 00419 found=true; 00420 break; 00421 } 00422 } 00423 00424 if (found) { 00425 int delta=m_wheelConfiguration[t].delta; 00426 unsigned int step=m_wheelConfiguration[t].step; 00427 ACS::Time timestamp; 00428 m_position_sp->getDevIO()->write(step+delta, timestamp); 00429 ACS_SHORT_LOG((LM_INFO,"Wheel rotaed to step %d",step+delta)); 00430 } 00431 else 00432 { 00433 ACS_SHORT_LOG((LM_ERROR,"No filters of type %s found",name->c_str())); 00434 } 00435 00436 DBConnector::writeCommand(getComponent()->getName(), "move", getStringifiedTimeStamp()); 00437 00438 completion = ACSErrTypeOK::ACSErrOKCompletion(); 00439 00440 // if OK action will be destroyed and we do not need it anymore 00441 if (name!=0) 00442 { 00443 delete name; 00444 name=0; 00445 } 00446 00447 // complete action requesting done invocation, 00448 // otherwise return reqInvokeWorking and set descOut.estimated_timeout 00449 return reqInvokeDone; 00450 } 00451 00452 ActionRequest 00453 FilterWheel::moveSlotAction ( 00454 BACIComponent *cob_p, 00455 const int &callbackID, 00456 const CBDescIn &descIn, 00457 BACIValue *value_p, 00458 Completion &completion, 00459 CBDescOut &descOut) 00460 { 00461 ACS_SHORT_LOG((LM_INFO,"::FilterWheel::moveSlotAction", "%s", getComponent()->getName())); 00462 00463 int* slot = static_cast<int*>(const_cast<void *>(value_p->pointerValue())); 00464 00465 ACS::Time timestamp; 00466 ACSErr::Completion_var compl; 00467 00468 ACSErr::Completion_var tempCompletion; 00469 unsigned int availableSlots = (unsigned int)m_slots_sp->get_sync(tempCompletion); 00470 if (*slot>=0 && *slot<(int)availableSlots) 00471 { 00472 m_position_sp->getDevIO()->write(m_wheelConfiguration[*slot].step, timestamp); 00473 ACS_SHORT_LOG((LM_INFO,"Wheel rotaed to step %d",m_wheelConfiguration[*slot].step)); 00474 } 00475 else 00476 { 00477 ACS_SHORT_LOG((LM_ERROR,"Invalid slot %d",*slot)); 00478 } 00479 00480 DBConnector::writeCommand(getComponent()->getName(), "move", getStringifiedTimeStamp()); 00481 00482 completion = ACSErrTypeOK::ACSErrOKCompletion(); 00483 00484 // if OK action will be destroyed and we do not need it anymore 00485 if (slot!=0) 00486 { 00487 delete slot; 00488 slot=0; 00489 } 00490 00491 // complete action requesting done invocation, 00492 // otherwise return reqInvokeWorking and set descOut.estimated_timeout 00493 return reqInvokeDone; 00494 } 00495 00496 /* --------------------- [ CORBA interface ] ----------------------*/ 00497 00498 void FilterWheel::moveFilterInBeam(const char* name, ACS::CBvoid_ptr cb, const ACS::CBDescIn& desc) 00499 { 00500 ACE_CString* str = new ACE_CString(name); 00501 00502 ACS_SHORT_LOG((LM_INFO,"FilterWheel::Move the filter %s in the beam",name)); 00503 getComponent()->registerAction(BACIValue::type_null, cb, desc, this, MOVEFILTER_ACTION, BACIValue(str)); 00504 } 00505 00506 void FilterWheel::moveSlotInBeam(int slot, ACS::CBvoid_ptr cb, const ACS::CBDescIn& desc) 00507 { 00508 int* slot_p= new int(slot); 00509 getComponent()->registerAction(BACIValue::type_null, cb, desc, this, MOVESLOT_ACTION, BACIValue(slot_p)); 00510 } 00511 00512 void FilterWheel::adjust(int step, ACS::CBvoid_ptr cb, const ACS::CBDescIn& desc) 00513 { 00514 int* step_p= new int(step); 00515 getComponent()->registerAction(BACIValue::type_null, cb, desc, this, ADJUST_ACTION, BACIValue(step_p)); 00516 } 00517 00518 CORBA::Long FilterWheel::calibrateWheel(int slot) 00519 { 00520 // Get the number of slots 00521 ACSErr::Completion_var completion; 00522 int availableSlots = (int)m_slots_sp->get_sync(completion); 00523 00524 if (slot>=0 && slot<availableSlots) { 00525 m_wheelConfiguration[slot].step=(long)m_position_sp->get_sync(completion); 00526 updateWheel(slot,m_wheelConfiguration[slot].step); 00527 ACS_SHORT_LOG((LM_INFO,"New step for slot %d is %d",slot,m_wheelConfiguration[slot].step)); 00528 return m_wheelConfiguration[slot].step; 00529 } else { 00530 ACS_SHORT_LOG((LM_ERROR,"Invalid slot %d",slot)); 00531 } 00532 return 0; 00533 } 00534 00535 CORBA::Long FilterWheel::calibrateFilter(const char* name) 00536 { 00537 // Get the number of slots 00538 ACSErr::Completion_var completion; 00539 unsigned int availableSlots = (unsigned int)m_slots_sp->get_sync(completion); 00540 00541 long actualPosition = (long)m_position_sp->get_sync(completion); 00542 long delta; 00543 00544 // Look for the filter to calibrate 00545 bool found=false; 00546 unsigned int t=0; 00547 for (; t<availableSlots; t++) { 00548 if (strcmp(name,m_wheelConfiguration[t].filterName)==0) { 00549 found=true; 00550 break; 00551 } 00552 } 00553 00554 if (found) { 00555 // Delta is given by the difference between the actual position 00556 // and step for the slot containing the filter 00557 long step=m_wheelConfiguration[t].step; 00558 m_wheelConfiguration[t].delta=actualPosition-step; 00559 updateFilter(name, m_wheelConfiguration[t].delta); 00560 ACS_SHORT_LOG((LM_INFO,"New delta for %s is %d",name,m_wheelConfiguration[t].delta)); 00561 } else { 00562 ACS_SHORT_LOG((LM_ERROR,"No filters of type %s found",name)); 00563 } 00564 00565 return delta; 00566 } 00567 00568 ACS::ROdouble_ptr 00569 FilterWheel::position () 00570 { 00571 if (m_position_sp == 0) 00572 { 00573 return ACS::ROdouble::_nil(); 00574 } 00575 00576 ACS::ROdouble_var prop = ACS::ROdouble::_narrow(m_position_sp->getCORBAReference()); 00577 return prop._retn(); 00578 } 00579 00580 ACS::ROstring_ptr 00581 FilterWheel::desc () 00582 { 00583 if (m_desc_sp == 0) 00584 { 00585 return ACS::ROstring::_nil(); 00586 } 00587 00588 ACS::ROstring_var prop = ACS::ROstring::_narrow(m_desc_sp->getCORBAReference()); 00589 return prop._retn(); 00590 } 00591 00592 ACS::ROlong_ptr 00593 FilterWheel::slots () 00594 { 00595 if (m_slots_sp == 0) 00596 { 00597 return ACS::ROlong::_nil(); 00598 } 00599 00600 ACS::ROlong_var prop = ACS::ROlong::_narrow(m_slots_sp->getCORBAReference()); 00601 return prop._retn(); 00602 } 00603 00604 /* --------------- [ MACI DLL support functions ] -----------------*/ 00605 #include <maciACSComponentDefines.h> 00606 MACI_DLL_SUPPORT_FUNCTIONS(FilterWheel) 00607 /* ----------------------------------------------------------------*/ 00608