Changeset 4481 for trunk/MagicSoft


Ignore:
Timestamp:
08/04/04 16:35:17 (20 years ago)
Author:
merck
Message:
MMerck: Laser positions are now doubles.
Location:
trunk/MagicSoft/AMC/activemirrorcontrol/activemirrorcontrol
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/AMC/activemirrorcontrol/activemirrorcontrol/amcmirrorpanel.cpp

    r3401 r4481  
    1515
    1616#include "amcmirrorpanel.h"
     17#include <math.h>
     18#include <qstring.h>
    1719
    1820AMCMirrorPanel::AMCMirrorPanel( int i, int j, int iType, int iPort, int iBox, int iDriver)
    1921                : m_i(i), m_j(j), m_iType(iType), m_iPort(iPort), m_iBox(iBox), m_iDriver(iDriver)
    2022{
     23        m_zReversed = false;
    2124        m_zLaserOn = false;
    2225        m_zMotorPower = true;
    2326        m_iX = m_iY = 0;
    2427        m_iRefX = m_iRefY = 0;
    25         m_iLaserX = m_iLaserY = 0;
     28        m_dLaserX = m_dLaserY = 0.0;
    2629        m_dAxisX = m_dAxisY = 0.0;
    2730        m_dSlopeX = m_dSlopeY = 0.0;
     
    3134AMCMirrorPanel::~AMCMirrorPanel(){
    3235}
     36
     37
     38/**
     39 * Here we calculation a correction for the laser spot position.
     40 *
     41 * The correction is composed of to components.
     42 * The first component cimes from the parabolic shape of the mirror.
     43 * Each mirror has a different focal length for the roque lamp spot
     44 * depending on its radial distance from the center of the mirror.
     45 * Correction one corrects for the error we introduce by moving the
     46 * mirror spot to a fixed focal plane during the roque lamp focusing.
     47 *
     48 * The second correction is to take into account the different position
     49 * of the plane where the roque lamp focusing is done and the plaane of the
     50 * winston cones.
     51 *
     52 * All calculations are done in mm.
     53 * We return the correction in milimeters we hace to move the laser spot along
     54 * the projection of the mirror center vector onto the camera plane.
     55 * This coorection is half the movement of the mirror spot.
     56 */
     57double AMCMirrorPanel::calcCorrection()
     58{
     59        // First we define some constants used in the calculation
     60        const double kDistMirror = 17000.0;             // Distance from camera to mirror center
     61                                                                                                                                                                        // Nominal focal length for infinity focusing
     62        const double kDistRoque = 980000.0;     // Distance from the MAGIC telescope to the
     63                                                                                                                                                                        // Roque lamp.
     64        const double kFocPlaneRoque = 300.1;    // change of focal plane for roque lamp focusing.
     65        const double kDistWinstonCones = 35.0;  // Distance from the plane of focusing ( white
     66                                                                                                                                                                        // paper or styropor surface) to the PMT camera
     67                                                                                                                                                                        // plane (front of winston cone surface)
     68
     69        /*
     70   * First we calculate the distance of the center of this panel to the center of the
     71         * mirror.
     72         */
     73  double dMirrorRadius = sqrt( pow( m_i*1000.0, 2 ) + pow( m_j*1000.0, 2 ) );
     74
     75        /*
     76   * dHeightMirror is the height of the center of the selected mirror panel over the
     77   * tangential plane to the parabolas vertex.
     78   * Using the equation for a parabola open to the right:
     79   *                         y^2 = 4ax
     80         *    a is the distance from the vertex to the focal point), or focal length of the parabola.
     81   *
     82         * This height is calculated to:
     83         *                        x = y^2 / 4a;
     84   * or
     85         *                        dHeightMirror = SQR( dMirrorRadius ) / dLatusRectum;
     86   *
     87   * where we used the latus rectum of the parabooa: dLatusRectum = 4 * a.
     88   *
     89   * See: http://mathworld.wolfram.com/Parabola.html
     90   */
     91        double dLatusRectum = 4.0 * kDistMirror;
     92        double dHeightMirror = pow( dMirrorRadius, 2. ) / dLatusRectum;
     93
     94  /*
     95   * Alpha is the angle betweeen the optical axis and the connection line
     96         * between the mirror center and the focal point of the parabola.
     97         * (The focal point of the parabola)
     98   *
     99         *
     100         *                                             ____-\         -
     101         *                                     ____----               ^
     102         *                             ____----                   dMirrorRadius
     103         *                                                                               ____----      dAlpha                   v
     104         *                 x------------------------------------|     -
     105         *
     106   *                 <------------ kDistMirror ------------>
     107   *                                                   <--->   dHeightMirror
     108   */
     109   double dAlpha = atan( dMirrorRadius / ( kDistMirror - dHeightMirror ) );
     110
     111        /*
     112         * For the Roque Lamp focusing the ray from the roque lamp is seen at the panels
     113   * center under an angle dDelta.
     114         *                   dDelta = atan( dMirrorRadius / (kDistRoque - dHeightMirror) );
     115         *
     116   *                                                           ________-\         -
     117         *                                           ________--------     __--          ^
     118         *                           ________--------                 __--        dMirrorRadius
     119         *                                       ________--------      dDelta                __--     dGamma        v           
     120   *   x-------------------------------------------------x--*-------------|       -
     121         *
     122   *   <--------------------------- kDistRoque --------------------------->
     123   *                                                     <- dFocusRoque -->
     124   *                                                                    <-kDistMirror->
     125   *                                                                    <->   dHeightMirror
     126   *
     127   * The reflected ray intersects the optical axis at a focal distance dFocusRoque
     128   * which is longer then focal length of the parabola.
     129   * For a spherical mirror (Davis-Cotton design like CT1) this difference would be
     130   * 300.1 mm which is the distance we shift the camera plane back for the roque lamp
     131   * focusing.
     132   * The angle at which this reflected ray intersects the optical axis is:
     133         *      dGamma = dAlpha - dDelta;
     134   *
     135   * For the parabola this distance is only correct for the vertex and bigger as farer the
     136   * mirror is away from the vertex. We calculate now the focal length at roque focusing
     137   * for this mirror dFocusRoque and the difference dDiffFocusRQ between the roque focusing
     138   * plane amd this focal length.
     139   */
     140        double dDelta = atan( dMirrorRadius / ( kDistRoque - dHeightMirror) );
     141        double dGamma = dAlpha - dDelta;
     142  double dFocusRoque = (dMirrorRadius / tan( dGamma )) + dHeightMirror;
     143        double dDiffFocusRQ = dFocusRoque - kFocPlaneRoque - kDistMirror;
     144
     145  /*
     146   * The correction we have to apply results from the error we made by forcing the spots of
     147   * the individual mirrors onto the focal spot of the vertex for the roque lamp distance.
     148         *
     149   *                                                        ____-\              -
     150         *                                                ____---- ..                 ^
     151         *                                        ____----     ....                   |
     152         *                                                            ____----________________________            |
     153         *                        ____----    |        ....              ^       dMirrorRadius
     154         *                ____----            |    ....              dCorrection      |
     155         *                        ____----                        |....                      V            V
     156   *   x--------------------------------*---------------------------------|     -
     157   *
     158   *   <--------------------------- dFocusRoque -------------------------->
     159   *                                    <- kDistMirror + kFocPlaneRoque -->
     160   *   <---  dDiffFocusRQ ------------->                         <--------> dHeightMirror
     161   *   <-------------- dFocusRoque - dHeightMirror ------------->
     162   *
     163   * Using the rule of three we get
     164   *
     165         *         dCorrection / dDiffFocusRQ = dMirrorRadius / ( dFocusRoque - dHeightMirror )
     166   * or:
     167   *         dCorrection = (dMirrorRadius / (dFocusRoque- dHeightMirror) ) * dDiffFocusRQ
     168   */
     169        double dCorrection1 = (dMirrorRadius / (dFocusRoque- dHeightMirror) ) * dDiffFocusRQ;
     170
     171  /*
     172   * The second correction needs to be applied because we can not use the front of the
     173   * winston cones as reference plane but a plane defined py the styropor panel put on
     174   * top of the plexiglas window of the camera.
     175   * This reference plane is 35 mm (kDistWinstonCones) infornt of the real focal plane we
     176   * should have used.
     177   * Looking at the scetch below we forced the ray to follow the line with stars, but
     178   * should have focus the mirror in such a way that it would have followed the dashed
     179   * line.
     180         *
     181   *                                                        ____--\              -
     182         *                                                ____---- ***                 ^
     183         *                                        ____----     ****                   |
     184         *                                                            ____----         ****         ---   |
     185         *                        ____----    |        ****              ^       dMirrorRadius
     186         *                ____----            |    ****              dCorrection      |
     187         *                        ____----                        |****                      V            V
     188   *   x--------------------------------*---------------------------------|     -
     189   *
     190   *                                    <- kDistMirror + kFocPlaneRoque -->
     191   *   <----- kDistWinstonCones ------->                             <----> dHeightMirror
     192   *                                                                                                                                    <- dFocus - dHeightMirror -->
     193   *
     194   * Using the rule of three we get
     195   *
     196         *         dCorrection / kDistWinstonCones = dMirrorRadius / ( dFocus - dHeightMirror - kDistWinstonCones )
     197   * or:
     198   *         dCorrection = (dMirrorRadius / (dFocus - dHeightMirror - kDistWinstonCones) ) * kDistWinstonCones
     199   */
     200  double dFocus = kDistMirror + kFocPlaneRoque;
     201  double dCorrection2 = (dMirrorRadius / (dFocus - dHeightMirror - kDistWinstonCones) ) * kDistWinstonCones;
     202
     203        return ( (dCorrection1 + dCorrection2) / 2.0 );
     204}
     205
     206/** No descriptions */
     207void AMCMirrorPanel::calcSteps( double p_dX, double p_dY, int& p_iStepsX, int& p_iStepsY )
     208{
     209        double dX = p_dX;
     210        double dY = p_dY;
     211        if( m_zReversed )
     212        {
     213                dX = p_dY;
     214                dY = p_dX;
     215        }
     216//      qDebug("Dx Dy: %4.0f %4.0f", dX, dY ); 
     217
     218        double dAlpha1 = atan( getSlopeX() );
     219        double dAlpha2 = atan( getSlopeY() );
     220//      qDebug("alpha1, alpha2: %7.2f %7.2f", dAlpha1 * 180.0 / 3.1415, dAlpha2 * 180.0 / 3.1415 );     
     221
     222        double dSinA1 = sin( dAlpha1 );
     223        double dSinA2 = sin( dAlpha2 );
     224        double dCosA1 = cos( dAlpha1 );
     225        double dCosA2 = cos( dAlpha2 );
     226
     227        double dFacX = dX - ( dY * dCosA2 / dSinA2 );
     228        dFacX /= ( dCosA1 - dSinA1 * dCosA2 / dSinA2 );
     229        double dFacY = ( dY - dFacX * dSinA1 ) / dSinA2;
     230//      qDebug("Factor x,y: %8.2f %8.2f", dFacX, dFacY );       
     231
     232        if( m_zReversed )
     233        {
     234                p_iStepsY = (int) ( dFacY * getConversionY() );
     235                p_iStepsX = (int) ( dFacX * getConversionX() );
     236        }
     237        else
     238        {
     239                p_iStepsX = (int) ( dFacX * getConversionX() );
     240                p_iStepsY = (int) ( dFacY * getConversionY() );
     241        }
     242
     243  // convert number of steps to an even number
     244        p_iStepsX = (p_iStepsX >> 1) << 1;
     245        p_iStepsY = (p_iStepsY >> 1) << 1;
     246}
     247
     248/**
     249 * Get the Reference position corrected for the errors introduced by trying
     250 * to focus with the roque lamp at a finite distance nad using the wrong
     251 * plane for the focusing procedure
     252 */
     253void AMCMirrorPanel::getCorrectedRef( double& p_dRefX, double& p_dRefY )
     254{
     255        const double  kPixelperMMX = 0.44;
     256        const double  kPixelperMMY = 0.44;
     257
     258        p_dRefX = getLaserX();
     259        p_dRefY = getLaserY();
     260        qDebug( "Laser spot position befor applying correction:   %f %f", p_dRefX, p_dRefY );
     261
     262  double dCorrection = calcCorrection();
     263        /*
     264         * The angle zeta is the angle of the mirror panel relative to the mirror center.
     265         * 0 degrees corresponds to panels (0,x) with x being a positve number.
     266         * The other angles are definedclockwise (positive) if looking onto the
     267         * mirror plane from the camera.
     268         */
     269        double dZeta = atan2( m_i * 1000.0, m_j * 1000.0 );
     270
     271        /*     
     272         * We assumethat the video camera is horizontally alligned with mirror dish.
     273         * If we have a rotation of the video image in respect to the mirror frame we
     274         * must add an extra correction here.
     275         * As the coordinate system of the video image has a reversed Y axis ( 0rign being
     276         * the upper left corner) we have to multiply the Y correction with -1. to get the right
     277         * sign.
     278         */
     279        double dCorrSpotX =        sin( dZeta ) * dCorrection;
     280        double dCorrSpotY = -1.0 * cos( dZeta ) * dCorrection;
     281
     282        p_dRefX += dCorrSpotY * kPixelperMMX;
     283        p_dRefY += dCorrSpotY * kPixelperMMY;
     284        qDebug( "Laser spot position after applying correction:   %f %f", p_dRefX, p_dRefY );
     285}
  • trunk/MagicSoft/AMC/activemirrorcontrol/activemirrorcontrol/amcmirrorpanel.h

    r3401 r4481  
    4444        /** mark this panel as installed in the dish */
    4545        void setInstalled( bool zInst) { m_zInstalled = zInst; }
     46        /** query if this panel is reversed for the axis */
     47        bool isReversed() const { return m_zReversed; }
     48        /** mark this panel as reversed for the axis */
     49        void setReversed( bool zRev) { m_zReversed = zRev; }
    4650        /** query if laser is on */
    4751        bool isLaserOn() const { return m_zLaserOn; }
     
    6973        void setRefY( int p_iY ) { m_iRefY = p_iY; }
    7074        /** get laser position X for reference position of motors */
    71         int getLaserX() const { return m_iLaserX; }
     75        double getLaserX() const { return m_dLaserX; }
    7276        /** set laser position X for reference position of motors */
    73         void setLaserX( int p_iX ) { m_iLaserX = p_iX; }
     77        void setLaserX( double p_dX ) { m_dLaserX = p_dX; }
    7478        /** get laser position Y for reference position of motors */
    75         int getLaserY() const { return m_iLaserY; }
     79        double getLaserY() const { return m_dLaserY; }
    7680        /** set laser position Y for reference position of motors */
    77         void setLaserY( int p_iY ) { m_iLaserY = p_iY; }
     81        void setLaserY( double p_dY ) { m_dLaserY = p_dY; }
    7882        /** get laser position Y for reference position of motors */
    7983        double getAxisX() const { return m_dAxisX; }
     
    108112        /** set laser position Y for reference position of motors */
    109113        void setStepsY( int p_iY ) { m_iStepsY = p_iY; }
     114  /** Here we calculation a correction for the laser spot position.
     115 */
     116  double calcCorrection();
     117  /** No descriptions */
     118  void calcSteps( double p_dX, double p_dY, int& p_iStepsX, int& p_iStepsY );
     119  /** No descriptions */
     120  void getCorrectedRef( double& p_dRefX, double& p_dRefY );
    110121
    111122private: // Public attributes
     
    118129        int m_iDriver;
    119130        bool m_zInstalled;
     131        bool m_zReversed;
    120132        /** Hold information if laser is on */
    121133        bool m_zLaserOn;
     
    131143        int m_iRefY;
    132144        /** Laser X position position for reference position. */
    133         int m_iLaserX;
     145        double m_dLaserX;
    134146        /** Laser Y position position for reference position. */
    135         int m_iLaserY;
     147        double m_dLaserY;
    136148        /** X axis of regression line for X motor. */
    137149        double m_dAxisX;
Note: See TracChangeset for help on using the changeset viewer.