File: WORKFLOW\TScanCmd.cpp

    1 #include "workflow\TScanCmd.h"
    2 
    3 extern TSteering Steering;
    4 extern TMain Main; // in MAIN.CPP deklariertes Hauptprogramm
    5 
    6 TScanCmd::TScanCmd ( TCmdTag ct ) : TCmd( ct ), Scaler(0)
    7 {
    8         // gibt fuer areascan im standardscan an ob psd-offset verwendet wird
    9         bChannelOffset= FALSE;
   10 
   11         // FIX Fehler 72
   12         bRestart= FALSE;
   13         // Schrittweitensteuerung deaktivieren + Art des Scans aus Kommando holen
   14         bDynamicStepWidth= FALSE;
   15         nStepScaleLevels= 0;
   16         Scaler= NULL;
   17         eCaller= ct.P1;
   18         // abhaengig von  der Art des Scans
   19         switch ( ct.P1 )
   20         {
   21                 // wenn AreaScan-kommando
   22                 case ForAreaScan:
   23                         // zum Kommando gehoeriges AreaScanFenster ermitteln + wenn keins
   24                         // existiert dann Fehlermeldung + abbruch
   25                         AreaScanW= (TAreaScanWindow*) Main.AreaScanWindow;
   26                         if ( !AreaScanW )
   27                         {
   28                                 #ifdef GermanVersion
   29                                         MessageBox( GetFocus(), "Kein AreaScan-Fenster offen", "Fehler", MBSTOP );
30 #else 31 MessageBox( GetFocus(), "No AreaScan-Window opened", "Failure", MBSTOP );
32 #endif 33 return; 34 } 35 // uebernehmen von Werten aus AreaScan + loeschen Datenbasis + 36 // neuzeichnen Fenster 37 bAbsorberUsed= AreaScanW->ReportUse.bAbsorber; 38 eScanType= AreaScanW->eScanType; 39 AreaScanW->New(); 40 AreaScanW->bMeasurementActive= TRUE; 41 AreaScanW->UpdateWnd(); 42 //Datum: 28.07.2002 bMonitorUsed= AreaScanW->ReportUse.bMonitor; 43 //Datum: 28.07.2002 if ( bMonitorUsed ) Monitor= AreaScanW->Monitor; 44 if ( AreaScanW->Monitor != 0 ) 45 Steering.Monitor= AreaScanW->Monitor; 46 47 switch ( eScanType ) 48 { 49 // bewegen omega + theta 50 case stOmega2ThetaScan: 51 // uebernehmen von Werten aus AreaScan 52 bOmega2Theta= TRUE; 53 // berechnen der Min- und Maxwerte incl. offset 54 dArgumentMin= AreaScanW->dOmegaMin - AreaScanW->dOffsetOmega; 55 dArgumentWidth= AreaScanW->dOmegaWidth; 56 dArgumentMax= AreaScanW->dOmegaMax - AreaScanW->dOffsetOmega; 57 dMoveRelation= AreaScanW->dMoveRelation; 58 dThetaMin= AreaScanW->d2ThetaStart - AreaScanW->dOffsetTheta + AreaScanW->dPsdOffset; 59 break; 60 61 // nur omega bewegen 62 case stStandardScan: 63 // uebernehmen von Werten aus AreaScan 64 // uebernehmen der 2Thetaposition ,die waehrend des scans 65 // beibehalten werden soll 66 dThetaMin= AreaScanW->d2ThetaStart; 67 bChannelOffset= mlIsAxisValid(Theta); 68 if ( AreaScanW->nMeasurementChannel != 0 ) 69 dThetaMin += AreaScanW->dPsdOffset; 70 bOmega2Theta= FALSE; 71 // berechnen der Min- und Maxwerte incl. offset 72 dArgumentMin= AreaScanW->dOmegaMin - AreaScanW->dOffsetOmega; 73 dArgumentWidth= AreaScanW->dOmegaWidth; 74 dArgumentMax= AreaScanW->dOmegaMax - AreaScanW->dOffsetOmega; 75 break; 76 77 default: 78 #ifdef GermanVersion 79 MessageBox( GetFocus(), "Scan-Start fehlgeschlagen.", "Steuerung", MBSTOP );
80 #else 81 MessageBox( GetFocus(), "Start Scan failed.", "Steering", MBSTOP );
82 #endif 83 } // switch (eScanType) 84 break; //ForAreaScan 85 86 // wenn Stepscan 87 case ForScan: 88 // zum Kommando gehöriges StepScanFenster ermitteln + wenn keins 89 // existiert, dann Fehlermeldung + abbruch 90 ScanW= (TScanWindow*) Main.ScanWindow; 91 if ( !ScanW ) 92 { 93 #ifdef GermanVersion 94 MessageBox( GetFocus(), "Kein Scan-Fenster offen", "Fehler", MBSTOP );
95 #else 96 MessageBox( GetFocus(), "No Scan-Window opened", "Failure", MBSTOP );
97 #endif 98 return; 99 } 100 // FIX Fehler 15 101 //Datum: 28.07.2002 bMonitorUsed= ScanW->bMonitorUsed; 102 //Datum: 28.07.2002 if ( bMonitorUsed ) Monitor= TDList::GetDetectorListPtr()->GetDetectorPtr(ScanW->Monitor->GetId()); 103 if ( ScanW->Monitor != 0 ) 104 Steering.Monitor= ScanW->Monitor; 105 106 // Absorber deaktivieren (nur bei Areascan) 107 bAbsorberUsed= FALSE; 108 // Werte für dynamische Schrittweitensteuerung aus Scanfenster holen 109 bDynamicStepWidth= ScanW->bDynamicStepWidth; 110 nStepScaleLevels= ScanW->nStepScaleLevels; 111 Scaler= &ScanW->Scaler; 112 // eingestellten Scantyp ermitteln (Standard oder Omega2Theta) 113 eScanType= ScanW->eScanType; 114 // Maincurve löschen, Fenster neuzeichnen ... 115 ScanW->New(); 116 // Messung als nicht unterbrochen und aktiv kennzeichnen 117 ScanW->bInterrupted= FALSE; 118 ScanW->bMeasurementActive= TRUE; 119 // neu zeichnen 120 ScanW->UpdateWnd(); 121 // abhaengig von eingest. Scantyp 122 switch ( eScanType ) 123 { 124 // wenn Omega2ThetaScan 125 case stOmega2ThetaScan: 126 // Omega2ThetaScan als aktiv kennzeichnen + Parameter wie 127 // Startwinkel,Endwinkel und normale Schrittweite des Omegamotors 128 // fuer den Scan aus Scanfenster holen + schrittverhaeltnis von Om. 129 // zu Theta auf 2 setzen 130 bOmega2Theta= TRUE; 131 dArgumentMin= ScanW->dArgumentMin; 132 dArgumentWidth= ScanW->dArgumentWidth; 133 dArgumentMax= ScanW->dArgumentMax; 134 dMoveRelation= 2.0; 135 // 2Thetastartpos. aus Scanfenster 136 dThetaMin= ScanW->d2ThetaStart; 137 break; 138 139 // wenn Standard-scan 140 case stStandardScan: 141 // Omega2ThetaScan als inaktiv kennzeichnen + Parameter wie 142 // Startwinkel, Endwinkel und normale Schrittweite des eingest. 143 // motors fuer den Scan aus Scanfenster holen 144 bOmega2Theta= FALSE; 145 dArgumentMin= ScanW->dArgumentMin; 146 dArgumentWidth= ScanW->dArgumentWidth; 147 dArgumentMax= ScanW->dArgumentMax; 148 break; 149 150 // unbekannter Scantyp(weder Standard- noch Omega2ThetaScan) 151 default: 152 #ifdef GermanVersion 153 MessageBox( GetFocus(), "Scan-Start fehlgeschlagen.", "Steuerung", MBSTOP );
154 #else 155 MessageBox( GetFocus(), "Start Scan failed.", "Steering", MBSTOP );
156 #endif 157 } // switch ( eScanType ) 158 break; //ForScan 159 160 // unbekannte Scanart(weder Step- noch AreaScan) 161 default: 162 #ifdef GermanVersion 163 MessageBox( GetFocus(), "Scan-Start", "Fehler", MBSTOP );
164 #else 165 MessageBox( GetFocus(), "Start Scan", "Steering", MBSTOP );
166 #endif 167 eStep= CReady; 168 bNoMeasure= TRUE; 169 return; 170 } // switch ( ct.P1 ) 171 172 // aktiven motor + aktive Pos. des Motors bestimmen 173 nMotor= mlGetAxis(); // Startup 174 mlGetDistance( nMotor, Steering.dStartPoint ); 175 // motor zum Startwinkel des Scans bewegen + dieser ist erster Messpunkt 176 StartMove( nMotor, dArgumentMin ); 177 dArgument= dArgumentMin; 178 // bei Om.2Th. akt. Winkel des Thetamotors bestimmen + auf Startpos. bewegen 179 // bei psd-offset im areascan(standardmodus) nur auf startposition fahren 180 if ( bOmega2Theta || bChannelOffset ) 181 { 182 nTheta= mlGetIdByName( Theta ); 183 mlGetDistance( nTheta, dStartPointTheta ); 184 // Thetaschrittweite berechnen 185 dThetaWidth= dArgumentWidth * dMoveRelation; 186 StartMove( nTheta, dThetaMin ); 187 dArgument2= dThetaMin; 188 } 189 // wenn absorber benutzt wird (nur AreaScan) dann aktuelle Pos. des 190 // Absorbermotors ermitteln und ihn auf Pos. 0.0 bewegen 191 if ( bAbsorberUsed ) 192 { 193 nAbsorber= mlGetIdByName( Absorber ); 194 //21.04.2004 bAbsorberMovedIn= FALSE; 195 //21.04.2004 bAbsorberActivated= FALSE; 196 mlGetDistance( nAbsorber, dStartPointAbsorber ); 197 StartMove( nAbsorber, 0.0 ); 198 } 199 // Ausgabe in Statuszeile + akt. Schritt des Scans auf ersten Schritt 200 // setzen + Anzahl der Voraussichtlich (ohne dyn. Schrittweite) zu 201 // erwartende Messpunkte 202 #ifdef GermanVersion 203 SetInfo( "Anfahren der Startposition ..." );
204 #else 205 SetInfo( "Move to startposition ..." );
206 #endif 207 eStep= CFirstStep; 208 nPointNumber= ( dArgumentMax - dArgumentMin ) / dArgumentWidth; 209 bNoMeasure= TRUE; 210 dwStartTimeTicks= 0; 211 }; 212 213 void TScanCmd::GetName ( LPSTR aName ) 214 { 215 strcpy( aName, "Scan" ); 216 } 217 218 bool TScanCmd::GetShowData ( LPSTR buffer ) 219 { 220 buffer[0]= 0; 221 float fTimeRemaining; 222 char fmt[ MaxString ]; 223 DWORD dwElapsedTicks; 224 225 if ( eStep == CReady ) 226 { 227 #ifdef GermanVersion 228 sprintf( buffer, "Scan abgeschlossen" );
229 #else 230 sprintf( buffer, "Scan Ready" );
231 #endif 232 } 233 else if ( eStep == CControlStep ) 234 { 235 // ermittelt zeit seit scanstart 236 dwElapsedTicks= GetTickCount() - dwStartTimeTicks; 237 238 /* bei ersten schritt verbleibende zeit =0.0 danach jeweils berechnen 239 wieviel zeit bisher pro Messpunkt gebraucht wurde und umrechnen , 240 wieviel dann für die folgenden Meßpunkte noch gebraucht wird 241 (funktioniert nicht bei dynam. Schrittweitensteuerung) 242 */ 243 if (nPointIdx) 244 { 245 fTimeRemaining= ( dwElapsedTicks / 60000.0 ) / nPointIdx; 246 fTimeRemaining *= ( nPointNumber - nPointIdx + 1 ); 247 } 248 else 249 fTimeRemaining= 0.0; 250 251 #ifdef GermanVersion 252 sprintf( fmt, "Scan ... Winkel= " ); 253 strcat( fmt, mGetDF() ); 254 strcat( fmt, " Intensität= %.3f" ); 255 // Aenderung Dynamische Schrittweite 256 // Ausgabe der verbleibenden Zeit nur, wenn keine dyn. Schrittweite 257 if (!bDynamicStepWidth) 258 strcat( fmt, " verbl. Zeit= %.1f Min." );
259 #else 260 sprintf( fmt, "Scan ... Angle= " ); 261 strcat( fmt, mGetDF() ); 262 strcat( fmt, " Intensity= %.3f" ); 263 // Aenderung Dynamische Schrittweite 264 // Ausgabe der verbleibenden Zeit nur, wenn keine dyn. Schrittweite 265 if (!bDynamicStepWidth) 266 strcat( fmt, " Time rem.= %.1f min." );
267 #endif 268 // string mit Param. füllen 269 sprintf( buffer, fmt, mGetValue( Distance ), Steering.GetIntensity(), fTimeRemaining ); 270 //Datum: 24.07.2002 SetInfo( buffer ); //!? scheinbar ueberfluessig (siehe Fkt.beschreibung) 271 //Datum: 24.07.2002 buffer[ 0 ]= 0; //!? scheinbar ueberfluessig (siehe Fkt.beschreibung) 272 } 273 return true; 274 } 275 276 ECmdCode TScanCmd::FirstStep ( void ) 277 { 278 // akt. Schritt= Controlschritt + anzahl bereits gemessener Punkte auf 0 + 279 // akt. Zeitwert sichern 280 eStep= CControlStep; 281 nPointIdx= 0; 282 dwStartTimeTicks= GetTickCount(); 283 return CMeasure; 284 }; 285 286 ECmdCode TScanCmd::ControlStep ( void ) 287 { 288 float fStepScaler= 1.0, fIntensity, fNorm; 289 int nScaleLevel= 0; 290 291 // wenn dyn. Schrittweite eingestellt dann vergleichen der gemessenen 292 // Intensitaet mit den Intensitaetswerten aus Scaler bei erstem 293 // Scaler-int.-wert, der groesser ist, wird die zu diesem scaler-int.-wert 294 // gehoerig Schrittweite als Schrittweitenfaktor festgelegt ansonsten 295 // bleibt dieser Faktor auf 1.0 296 // FIX Fehler 72 Diff./Refl. 297 if (!bRestart) 298 { 299 if ( bDynamicStepWidth ) 300 { 301 fIntensity= Steering.GetIntensity(); 302 // auch die Scalerwerte muessen durch Monit.int. normiert werden 303 fNorm= ( Steering.GetNorm() != 0.0 ) ? Steering.GetNorm() : 1.0; 304 while ( nScaleLevel < nStepScaleLevels ) 305 { 306 if ( fIntensity > ( Scaler->GetAt(nScaleLevel) / fNorm ) ) 307 { 308 nScaleLevel++; 309 continue; 310 } 311 fStepScaler= Scaler->GetAt(nScaleLevel + nMaxScaleIdx); 312 break; 313 } 314 } 315 316 // wenn aktuelle Pos. des motors noch kleiner als endwinkel des Scans dann 317 // anzahl gemessener Punkte erhoehen + naechsten Meßpunkt des Motors 318 // berechnen (dabei schrittweite beachten) + anfahren dieses Punktes 319 // bei Omega2Theta den Thetamotor auf neue pos. bewegen 320 // FIX Fehler 75 321 if ( Steering.GetDistance() < dArgumentMax ) 322 { 323 nPointIdx++; 324 dArgument += dArgumentWidth * fStepScaler; 325 StartMove( nMotor, dArgument ); 326 if ( bOmega2Theta ) 327 { 328 dArgument2 += dThetaWidth * fStepScaler; 329 StartMove( nTheta, dArgument2 ); 330 } 331 return CRecall; 332 } 333 } 334 else 335 { // FIX Fehler 72 Diff./Refl. 336 bRestart= FALSE; 337 StartMove( nMotor, dArgument ); 338 if ( bOmega2Theta) 339 StartMove( nTheta, dArgument2 ); 340 return CRecall; 341 } 342 343 // wenn endwinkel erreicht (bzw. darueber hinaus) dann naechsten Schritt als 344 // Endschritt kennzeichnen + aktiven Motor (und ev. Theta)auf Position vor 345 // start des Scan zurueckbewegen 346 eStep= CReadyStep; 347 bNoMeasure= TRUE; 348 StartMove( nMotor, Steering.dStartPoint ); 349 if ( bOmega2Theta || bChannelOffset) 350 StartMove( nTheta, dStartPointTheta ); 351 return CRecall; 352 }; 353 354 ECmdCode TScanCmd::ReadyStep ( void ) 355 { 356 // naechster schritt soll scan beenden (wird ReadyReaction aufrufen) 357 eStep= CReady; 358 switch ( eCaller ) 359 { 360 // bei Stepscan die messung als nicht aktiv kennzeichnen 361 case ForScan: 362 ScanW->bMeasurementActive= FALSE; 363 break; 364 } 365 return CRecall; 366 }; 367