Commit d0604c1e authored by Andrea Orlati's avatar Andrea Orlati
Browse files

fix issue #885: new partial release. All component logic and configuration...

 fix issue #885: new partial release. All component logic and configuration are now in place. Also simple controls (calibration mark for example) are implemented.
 Still missing: readout of LNA bias paramenters. Contro of the LNA bypass mode. Implmentations of the Local Oscillators. Also a test should be done before merging into parent
 branch.
parent 94988f7f
Loading
Loading
Loading
Loading
+16 −35
Original line number Diff line number Diff line
@@ -18,42 +18,21 @@
<xs:complexType name="KQWBandReceiverModeType">
    <!-- Mode name or mode mnemonic code -->
    <xs:attribute name="Mode" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the sky radio frequency band of the K band receiver (0..IFs) -->
    <xs:attribute name="KBandRFMin" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the sky radio frequency band of the Q band receiver (0..IFs) -->
    <xs:attribute name="QBandRFMin" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the sky radio frequency band of the first W band receiver (0..IFs) -->
    <xs:attribute name="W1BandRFMin" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the sky radio frequency band of the second W band receiver (0..IFs) -->
    <xs:attribute name="W2BandRFMin" type="xs:string" use="required"/>  
    <!-- blank separated list of the starting frequencies (MHZ) relative to each of the IF for the K, Q, W1, and W2 band receiver respectively -->
    <!-- the first entry is relative to IF 0.  -->
    <xs:attribute name="RFMin" type="xs:string" use="required"/>
 
    <!-- represent the upper value (MHZ) of the sky radio frequency band of the K band receiver (0..IFs) -->
    <xs:attribute name="KBandRFMax" type="xs:string" use="required"/>
    <!-- represent the upper value (MHZ) of the sky radio frequency band of the Q band receiver (0..IFs) -->
    <xs:attribute name="QBandRFMax" type="xs:string" use="required"/>
    <!-- represent the upper value (MHZ) of the sky radio frequency band of the first W band receiver (0..IFs) -->
    <xs:attribute name="W1BandRFMax" type="xs:string" use="required"/>
    <!-- represent the upper value (MHZ) of the sky radio frequency band of the second W band receiver (0..IFs) -->
    <xs:attribute name="W2BandRFMax" type="xs:string" use="required"/>  
    <!-- blank separated list of the upper value (MHZ) of the sky radio band relative to each of the IF for the K, Q, W1, and W2 band receiver respectively -->
    <!-- the first entry is relative to IF 0.  -->    
    <xs:attribute name="RFMax" type="xs:string" use="required"/>
    
    <!-- blank separated list of the starting frequencies (MHZ) of the IF band relative to each of the IF for the K, Q, W1, and W2 band receiver respectively -->
    <!-- the first entry is relative to IF 0.  -->
    <xs:attribute name="IFMin" type="xs:string" use="required"/>
 
    <!-- represent the lower value (MHZ) of the Intermediate Frequency band of the K band receiver (0..IFs)-->
    <xs:attribute name="KBandIFMin" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the Intermediate Frequency band of the Q band receiver (0..IFs)-->
    <xs:attribute name="QBandIFMin" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the Intermediate Frequency band of the W1 band receiver (0..IFs)-->
    <xs:attribute name="W1BandIFMin" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the Intermediate Frequency band of the W2 band receiver (0..IFs)-->
    <xs:attribute name="W2BandIFMin" type="xs:string" use="required"/>
    
    <!-- represent the upper value (MHZ) of the Intermediate Frequency band of the K band receiver (0..IFs)-->
    <xs:attribute name="KBandIFMax" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the Intermediate Frequency band of the Q band receiver (0..IFs)-->
    <xs:attribute name="QBandIFMax" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the Intermediate Frequency band of the W1 band receiver (0..IFs)-->
    <xs:attribute name="W1BandIFMax" type="xs:string" use="required"/>
    <!-- represent the lower value (MHZ) of the Intermediate Frequency band of the W2 band receiver (0..IFs)-->
    <xs:attribute name="W2BandIFMax" type="xs:string" use="required"/>
    <!-- blank separated list of the upper value (MHZ) of the IF band relative to each of the IF for the K, Q, W1, and W2 band receiver respectively -->
    <!-- the first entry is relative to IF 0.  -->    
    <xs:attribute name="IFMax" type="xs:string" use="required"/>
    
    
    <!-- number of virtual feeds -->
@@ -76,6 +55,8 @@
    <!-- Maximum LO value (MHZ) -->
    <xs:attribute name="LOMax" type="xs:string" use="required"/>
    
    <xs:attribute name="ActivateBypass" type="xs:boolean" use="required" />

</xs:complexType>

<xs:element name="KQWBandReceiverModeSetup" type="KQWBandReceiverModeType"/>
+6 −2
Original line number Diff line number Diff line
@@ -140,8 +140,12 @@
        <xs:attribute name="RepetitionExpireTime" type="xs:unsignedLong" use="required" />
        <!-- Instance of the associated device that will set the local oscillator -->
        <xs:attribute name="DefaultMode" type="xs:string" use="required"/>
        <!-- Name of the LocalOscillator component -->
        <xs:attribute name="LocalOscillatorInstance" type="xs:string" use="required"/>
        <!-- Name of the LocalOscillator component serving the K band -->
        <xs:attribute name="LocalOscillator_K_Instance" type="xs:string" use="required"/>
        <!-- Name of the LocalOscillator component serving the Q band -->
        <xs:attribute name="LocalOscillator_Q_Instance" type="xs:string" use="required"/>
        <!-- Name of the LocalOscillator component serving the W band -->
        <xs:attribute name="LocalOscillator_W_Instance" type="xs:string" use="required"/>

      </xs:extension>
     </xs:complexContent>
+524 −0
Original line number Diff line number Diff line
#ifndef _BASECOMPONENTCORE_H_
#define _BASECOMPONENTCORE_H_

/***********************************************************************\
 IRA Istituto di Radioastronomia                                 
 This code is under GNU General Public License (GPL).          
                                                              
 Andrea Orlati (aorlati@ira.inaf.it): Author
\***********************************************************************/

#include "Configuration.h"
#include <ReceiverControl.h>
#include <LocalOscillatorInterfaceC.h>
#include <ReceiversErrors.h>
#include <ManagmentDefinitionsC.h>
#include "utils.h"

/**
 * This class contains the code of almost all the features  of the component
 * @author <a href=mailto:a.orlati@ira.cnr.it>Andrea Orlati</a>,
 * Istituto di Radioastronomia, Italia
 * <br>
  */
class CComponentCore {

public:

    CComponentCore();
    virtual ~CComponentCore();


    /**
     * This method initializes the object
     * @param service pointer to container services object provided by the container
     */
    virtual void initialize(maci::ContainerServices* services);


    /**
     * This method prepares the object for execution.
     * @return the pointer to the configuration class
     * @throw (ComponentErrors::CDBAccessExImpl, ComponentErrors::MemoryAllocationExImpl, ComponentErrors::SocketErrorExImpl,
     *       ReceiversErrors::ModeErrorExImpl)
     */
    virtual CConfiguration<maci::ContainerServices> const * const execute();
    

    /**
     * This function is responsible to free all allocated resources
     */
    virtual void cleanup();


    /*
     * It sets the local oscillators. Before commanding the new value 
     * some check are done. The  corresponding signal amplitude is computed.
     * @param lo lists of values for the local oscillator (MHz), one for each IF. 
     * In that case just the first one is significant. In a -1 is passed the present value is kept.
     * @throw  ComponentErrors::ValidationErrorExImpl
     * @throw ComponentErrors::ValueOutofRangeExImpl
     * @throw ComponentErrors::CouldntGetComponentExImpl
     * @throw ComponentErrors::CORBAProblemExImpl
     * @thorw ReceiversErrors::LocalOscillatorErrorExImpl
     */
    void setLO(const ACS::doubleSeq& lo);

    /**
     * It activate the receiver, in other words it allows to setup the default configuration 
     * and to make sure the LNA are turned on.
     * @throw ReceiversErrors::ModeErrorExImpl,
     * @throw ComponentErrors::ValidationErrorExImpl,
     * @throw ComponentErrors::ValueOutofRangeExImpl,
     * @throw ComponentErrors::CouldntGetComponentExImpl,
     * @throw ComponentErrors::CORBAProblemExImpl,
     * @throw ReceiversErrors::LocalOscillatorErrorExImpl,
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl,
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void activate();

    /**
     * It deactivates the receiver.
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void deactivate();


    /**
     * It allows to compute the value of the calibration mark for any given sub bands in 
     * the IF space.
     * @param result this the sequence of computed mark values, the first entry correspond to 
     * first sub band and so on....
     * @param, resFreq the sequence reports the initial observed sky frequency (MHz), the  
     * first entry correspond to first sub band and so on....
     * @param resBw the sequence reports the real bandwidth observed (MHz), the  first entry 
     * correspond to first sub band and so on....
     * @param freqs  list of start frequencies (MHz)
     * @param bandwidth list of the band widths (MHz)
     * @param feeds list of feed identifier, it allows to specifies form which feed the sub 
     * band comes from. In that case it is neglected since the receiver is a single feed
     * @param ifs list of IF identifier, it allows to specifies from which receiver IF the 
     * sub band comes from.
     * @param scale value to scale tsys measurement
     * @throw ComponentErrors::ValidationErrorExImpl
     * @throw ComponentErrors::ValueOutofRangeExImpl
     */
    void getCalibrationMark(
            ACS::doubleSeq& result,
            ACS::doubleSeq& resFreq,
            ACS::doubleSeq& resBw,
            const ACS::doubleSeq& freqs,
            const ACS::doubleSeq& bandwidths,
            const ACS::longSeq& feeds,
            const ACS::longSeq& ifs,
            bool& onoff,
            double &scale
     );

    /**
     * It is called to get the all the receiver output information in one call.
     * An output is identified by providing the feed and the IF identifier. It can process any number of requests at a time.
     * @param feeds is a list that stores the corresponding feed of the output we are asking for
     * @param ifs is a list that identifies which IFs of the feed we are interested in, usually 0..<i>IFs</i>-1
     * @param freq used to return the start frequency of the band provided by the output  the oscillator
     * (if present) is not  added (MHz)
     * @param bw used to return the total provided bandwidth. (MHz)
     * @param pols it specifies the polarization of the receiver output, since ACS does not support for enum
     * sequences the correct value must be matched against the <i>Receivers::TPolarization</i> enumeration.
     * @param LO it gives (if present) the value of the local oscillator (MHz).
     * @throw ComponentErrors::ValidationErrorExImpl
     * @throw ComponentErrors::ValueOutofRangeExImpl
     */
     void getIFOutput(
             const ACS::longSeq& feeds,
             const ACS::longSeq& ifs,
             ACS::doubleSeq& freqs,
             ACS::doubleSeq& bw,
             ACS::longSeq& pols,
             ACS::doubleSeq& LO
     );



    /**
     * It computes the taper given a reference band.
     * @param freq start frequency of the reference band
     * @param bw width of the reference band
     * @param feed feed number
     * @param ifNumber IF chain identifier
     * @param waveLen wave length of the reference band, the band is transformed in a real sky 
     * observed band and the the central frequency is taken.
     * @throw ComponentErrors::ValidationErrorExImpl 
     * @thorw ComponentErrors::ValueOutofRangeExImpl
     */
    double getTaper(
            const double& freq,
            const double& bw,
            const long& feed,
            const long& ifNumber,
            double& waveLen
    );


    /** It turns the calibration diode on.
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl
     * @throw ComponentErrors::ValidationErrorExImpl
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl    
    */
    void calOn();


    /** It turns the calibration diode off
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl
     * @throw ComponentErrors::ValidationErrorExImpl
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl    
     */
    void calOff();


    /** It turns the external calibration diode on.
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl
     * @throw ComponentErrors::ValidationErrorExImpl
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
    */
    void externalCalOn();

    /** It turns the external calibration diode off.
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl
     * @throw ComponentErrors::ValidationErrorExImpl
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
    */
    void externalCalOff();

    /** It turns on the sensor for vacuum measurement.
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
    */
    void vacuumSensorOn();


    /** It turns off the sensor for vacuum measurement.
     * @throw ReceiversErrors::NoRemoteControlErrorExImpl
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl)
    */
    void vacuumSensorOff();


    /** It allows to turn LNA on
    * @throw ReceiversErrors::NoRemoteControlErrorExImpl
    * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl)
    */
    void lnaOn();


    /** It allows to turn LNA off
    * @throw ReceiversErrors::NoRemoteControlErrorExImpl
    * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl)
    */
    void lnaOff();


    /**
     * It reads and updates from the control board the current value of the vacuum
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateVacuum();


    /**
     * It check if the vacuum pump is on and check is the status is fault or not (<i>VACUUMPUMPFAULT</i>)
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateVacuumPump();


    /**
     * It checks if the vacuum valve is opened or not
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateVacuumValve();


    /**
     * It reads and updates from the control board the current cryo temperature measured near the cool head
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateCryoCoolHead();


    /**
     * It reads and updates from the control board the current cryo temperature measured near the cool head window
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateCryoCoolHeadWin();


    /**
     * It reads and updates from the control board the current cryo temperature measured near the LNA
     */
    void updateCryoLNA();


    /**
     * It reads and updates from the control board the current cryo temperature measured near the LNA window
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateCryoLNAWin();


    /**
     * It reads and updates from the control board the current vertex temperature
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateVertexTemperature();


    /**
     * It checks if the Dewar power box is in remote or not
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateIsRemote();


    /**
     * It checks if the cool head is turned on or not
     * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl
     */
    void updateCoolHead();


    /**
     * It checks is the status of the noise mark correspond to the commanded status, 
     * otherwise it sets the <i>NOISEMARKERROR</i> bit. It also check if the
     * external control of the noise mark has been enabled or not
     */
    void updateNoiseMark();


    /**
     * This method resumes the whole status of the component. It set the <i>componentStatus</i> member variable.
     */
    void updateComponent();


    /**
     * This is getter method. No need to make it thread safe......
     * @return the current value of the vacuum in mbar
     */
    double getVacuum() const { return m_vacuum; }


    /**
     * This is getter method. No need to make it thread safe......
     * @return the current value of the cryogenic temperature at cool head in °K
     */
    CConfiguration<maci::ContainerServices>::BoardValue getCryoCoolHead() const { return m_cryoCoolHead; }


    /**
     * This is getter method. No need to make it thread safe......
     * @return the current value of the cryogenic temperature at cool head window in °K
     */
    CConfiguration<maci::ContainerServices>::BoardValue getCryoCoolHeadWin() const { return m_cryoCoolHeadWin; }


    /**
     * This is getter method. No need to make it thread safe......
      * @return the current value of the cryogenic temperature at LNA in °K
     */
    CConfiguration<maci::ContainerServices>::BoardValue getCryoLNA() const { return m_cryoLNA; }


    /**
     * This is getter method. No need to make it thread safe......
     * @return the current value of the cryogenic temperature at LNA  window in °K
     */
    CConfiguration<maci::ContainerServices>::BoardValue getCryoLNAWin() const { return m_cryoLNAWin; }


    /**
     * This is getter method. No need to make it thread safe......
     * @return the current vertex temperature in °K
     */
    CConfiguration<maci::ContainerServices>::BoardValue getVertexTemperature() const { return m_envTemperature; }


    /**
     * This is getter method. No need to make it thread safe......
     * @return the current status word
     */
    DWORD getStatusWord() const  { return  m_statusWord; }


    /**
     * It returns the feed geometry of the receiver with respect to the central one. 
     * For this implementation it is just a placeholder since there is just one feed.
     */
    long getFeeds(ACS::doubleSeq& X, ACS::doubleSeq& Y, ACS::doubleSeq& power);

    /**
     * It returns the current operating mode of the receiver.
     * @return output string
     */
    const IRA::CString& getActualMode();

    /**
     * It returns the number of IF chains for each feed
     * @return output value
     */
    const DWORD& getIFs();


    /**
     * It returns the number of feeds
     * @return output value
     */
    const DWORD& getFeeds();

    /**
     * @return the status flag of the component
     */
    const Management::TSystemStatus& getComponentStatus();

    /**
     * Allows to set the "default_value" for the vacuum characteristic. In principle it is possible 
     * to read it directly from CDB, but I found it more
     * comfortable to get it directly from the characteristic itself.
     */
    inline void setVacuumDefault(const double& val) { m_vacuumDefault=val; }
    
    void getBandwidth(ACS::doubleSeq& bw);
    void getInitialFreq(ACS::doubleSeq& f);
    void getLocalOscillator(ACS::doubleSeq& lo);
    void getPolarizations(ACS::longSeq& pol);

    /** 
     * This is a pure virtual function, so you must write it in your derived class.
     * It allows to change the operating mode of the receiver. 
     * If the mode does not correspond to a valid mode an error is thrown.
     * @param  mode mode code as a string
	  * @throw ComponentErrors::ValidationErrorExImpl
     * @throw ComponentErrors::ValueOutofRangeExImpl
     * @throw ComponentErrors::CouldntGetComponentExImpl
     * @throw ComponentErrors::CORBAProblemExImpl
     * @throw ReceiversErrors::LocalOscillatorErrorExImpl
     * @throw ComponentErrors::CDBAccessExImpl
     * @throw ReceiversErrors::ModeErrorExImpl
     */
    virtual void setMode(const char * mode);


protected:

    /** Obtain a valid reference to the local oscillator device
	  * @throw ComponentErrors::CouldntGetComponentExImpl   
     */
    void loadLocalOscillator();


    /** Used to free the reference to the local oscillator device */
    void unloadLocalOscillator();


    /************************ CONVERSION FUNCTIONS **************************/
    // Convert the voltage value of the vacuum to mbar
    static double voltage2mbar(double voltage) { return(pow(10, 1.5 * voltage - 12)); }


    // Convert the voltage value of the temperatures to Kelvin
    static double voltage2Kelvin(double voltage) {
        return voltage < 1.12 ? \
                  (660.549422889947 * pow(voltage, 6)) - (2552.334255456860 * \
                  pow(voltage, 5)) + (3742.529989384570 * pow(voltage, 4)) - \
                  (2672.656926956470 * pow(voltage, 3)) + (947.905578508975 * \
                  pow(voltage, 2)) - 558.351002849576 * voltage + 519.607622398508 \
                :
                  (865.747519105672 * pow(voltage, 6)) - (7271.931957100480 * \
                  pow(voltage, 5)) + (24930.666241800500 * pow(voltage, 4)) - \
                  (44623.988512320400 * pow(voltage, 3)) + (43962.922216886600 * \
                  pow(voltage, 2)) - 22642.245121997700 * voltage + 4808.631312836750;
    }


    // Convert the voltage value of the temperatures to Celsius (Sensor B57703-10K)
    static double voltage2Celsius(double voltage) 
    { return -5.9931 * pow(voltage, 5) + 40.392 * pow(voltage, 4) - 115.41 * pow(voltage, 3) + 174.67 * pow(voltage, 2) - 174.23 * voltage + 112.79; }

    // Convert the ID voltage value to the mA value
    static double currentConverter(double voltage) { return(10 * voltage); }


    // Convert the VD and VG voltage values using a right scale factor
    static double voltageConverter(double voltage) { return(voltage); }
    /********************** END CONVERSION FUNCTIONS ***********************/

    enum TStatusBit {
        LOCAL=0,
        VACUUMSENSOR=1,
        VACUUMPUMPSTATUS=2,
        VACUUMPUMPFAULT=3,
        VACUUMVALVEOPEN=4,
        COOLHEADON=5,
        COMPRESSORFAULT=6,
        NOISEMARK=7,
        NOISEMARKERROR=8,
        EXTNOISEMARK=9,
        CONNECTIONERROR=10,
        UNLOCKED=11
    };


    /** This function will set the a status bit. It may be considered thread safe due to its definition */
    inline void setStatusBit(TStatusBit bit) { m_statusWord |= 1 << bit; }


    /** This function will unset (clear) a status bit. It may be considered thread safe due to its definition */
    inline void clearStatusBit(TStatusBit  bit) { m_statusWord &= ~(1 << bit); }


    /** This function check is a bit is set or not. It may be considered thread safe due to its definition */
    inline bool checkStatusBit(TStatusBit bit) { return m_statusWord & (1 << bit); }


    CConfiguration<maci::ContainerServices> m_configuration;
    IRA::ReceiverControl *m_control; // This object is thread safe
    BACIMutex m_mutex;
    //IRA::CString m_actualMode;
    //IRA::CString m_setupMode; 


private:

    maci::ContainerServices* m_services;
    Receivers::LocalOscillator_var m_localOscillatorDevice;
    bool m_localOscillatorFault;
    //double m_localOscillatorValue;
    double m_vacuum;
    CConfiguration<maci::ContainerServices>::BoardValue m_cryoCoolHead;
    CConfiguration<maci::ContainerServices>::BoardValue m_cryoCoolHeadWin;
    CConfiguration<maci::ContainerServices>::BoardValue m_cryoLNA;
    CConfiguration<maci::ContainerServices>::BoardValue m_cryoLNAWin;
    CConfiguration<maci::ContainerServices>::BoardValue m_envTemperature;
    double m_vacuumDefault;
    bool m_calDiode;
    IRA::ReceiverControl::FetValues m_fetValues;
    DWORD m_statusWord;
    // m_ioMarkError is a flag used to know if we already got an IO
    // error.
    bool m_ioMarkError;
    Management::TSystemStatus m_componentStatus;

    void setComponentStatus(const Management::TSystemStatus& status) 
    { 
        if (status>m_componentStatus) m_componentStatus=status;  
    }
    
    double linearFit(ACS::doubleSeq& X,ACS::doubleSeq& Y, const WORD& size, double x) const;

    double linearFit(double *X,double *Y,const WORD& size,double x) const;

};

#endif
+142 −242

File changed.

Preview size limit exceeded, changes collapsed.

+79 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading