Changeset 4481 for trunk/MagicSoft/AMC
- Timestamp:
- 08/04/04 16:35:17 (20 years ago)
- Location:
- trunk/MagicSoft/AMC/activemirrorcontrol/activemirrorcontrol
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/AMC/activemirrorcontrol/activemirrorcontrol/amcmirrorpanel.cpp
r3401 r4481 15 15 16 16 #include "amcmirrorpanel.h" 17 #include <math.h> 18 #include <qstring.h> 17 19 18 20 AMCMirrorPanel::AMCMirrorPanel( int i, int j, int iType, int iPort, int iBox, int iDriver) 19 21 : m_i(i), m_j(j), m_iType(iType), m_iPort(iPort), m_iBox(iBox), m_iDriver(iDriver) 20 22 { 23 m_zReversed = false; 21 24 m_zLaserOn = false; 22 25 m_zMotorPower = true; 23 26 m_iX = m_iY = 0; 24 27 m_iRefX = m_iRefY = 0; 25 m_ iLaserX = m_iLaserY =0;28 m_dLaserX = m_dLaserY = 0.0; 26 29 m_dAxisX = m_dAxisY = 0.0; 27 30 m_dSlopeX = m_dSlopeY = 0.0; … … 31 34 AMCMirrorPanel::~AMCMirrorPanel(){ 32 35 } 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 */ 57 double 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 */ 207 void 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 */ 253 void 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 44 44 /** mark this panel as installed in the dish */ 45 45 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; } 46 50 /** query if laser is on */ 47 51 bool isLaserOn() const { return m_zLaserOn; } … … 69 73 void setRefY( int p_iY ) { m_iRefY = p_iY; } 70 74 /** get laser position X for reference position of motors */ 71 int getLaserX() const { return m_iLaserX; }75 double getLaserX() const { return m_dLaserX; } 72 76 /** 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; } 74 78 /** get laser position Y for reference position of motors */ 75 int getLaserY() const { return m_iLaserY; }79 double getLaserY() const { return m_dLaserY; } 76 80 /** 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; } 78 82 /** get laser position Y for reference position of motors */ 79 83 double getAxisX() const { return m_dAxisX; } … … 108 112 /** set laser position Y for reference position of motors */ 109 113 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 ); 110 121 111 122 private: // Public attributes … … 118 129 int m_iDriver; 119 130 bool m_zInstalled; 131 bool m_zReversed; 120 132 /** Hold information if laser is on */ 121 133 bool m_zLaserOn; … … 131 143 int m_iRefY; 132 144 /** Laser X position position for reference position. */ 133 int m_iLaserX;145 double m_dLaserX; 134 146 /** Laser Y position position for reference position. */ 135 int m_iLaserY;147 double m_dLaserY; 136 148 /** X axis of regression line for X motor. */ 137 149 double m_dAxisX;
Note:
See TracChangeset
for help on using the changeset viewer.