File: AUTOJUST\M_JUSTAG.CPP

    1 #include "utils\u_utils.h"
    2 #include "winresrc\rc_def.h" // Ressourcen-IDs
    3 #include "help\help_def.h"   // Help-IDs
    4 #pragma hdrstop
    5 
    6 #include "swintrac\m_dlg.h" // für TCounterWindow
    7 
    8 // Interface zur Motorsteuerung
    9 #include "motrstrg\motrstrg.h"
   10 
   11 // Interface zur Detektorsteuerung (sehr spartanisch)
   12 #include "detecuse\detecuse.h"
   13 
   14 // Dialog automatische Justage
   15 #include "autojust\autojust.h"
   16 
   17 #include "autojust\matrix.h"
   18 #include "autojust\transfrm.h"
   19 #include "autojust\m_justag.h"
   20 
   21 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   22 
   23 // Globale Definition der Motorachsen
   24 // -> Zugriff durch alle Justage- & Tranformationsobjekte möglich
   25 int nMotorTL= -1, nMotorDF= -1, nMotorCC= -1;
   26 
   27 // Globales Flag für Schreiben in Justagelog
   28 bool bWriteLogfile;
   29 
   30 // Statusmeldungen in Prokolldatei für die Automatische Justage schreiben
   31 void WriteToJustageLog(char *buf)
   32 {
   33         FILE *hLogFile;
   34 
   35         if ( (hLogFile= fopen("Justage.log", "a+")) == NULL )
   36                 MessageBox(GetFocus(), "WriteToJustageLog: Fehler beim Öffnen von Justage.log", "fopen", MBSTOP);
   37 
   38         if ( fwrite(buf, 1, strlen(buf), hLogFile) != strlen(buf) )
   39                 MessageBox(GetFocus(), "WriteToJustageLog: Fehler beim Schreiben in Justage.log", "fwrite", MBSTOP);
   40 
   41         if ( fclose(hLogFile) == EOF )
   42                 MessageBox(GetFocus(), "WriteToJustageLog: Fehler beim Schließen von Justage.log", "fclose", MBSTOP);
   43 }
   44 
   45 //**************** Dialog Automatische Justage*********************************
   46 //**************** Selbstständiges Einstellen der Probe************************
   47 
   48 TAutomaticAngleControlDlg::TAutomaticAngleControlDlg( void ): TModalDlg("AutomaticAngleControl", GetMainInstance()),
   49                 status(0), buf(0), buf1(0), m_lnkTimer(0), Transform(0)
   50 {
   51         m_lnkTimer= new TInterfaceTimer( this, 100 ); //Observer, d.h. Timer benachrichtigt uns
   52 
   53         nMaxString= 32767;
   54         status= new char[nMaxString];
   55         if (!status)
   56         {
   57                 MessageBox("Fehler bei Speicherreservierung", "TAutomaticAngleControlDlg", MBSTOP);
   58                 PostQuitMessage( -1);
   59         }
   60         else
   61         {
   62                 buf= new char[1024];
   63                 if (!buf)
   64                 {
   65                         MessageBox("Fehler bei Speicherreservierung", "TAutomaticAngleControlDlg", MBSTOP);
   66                         PostQuitMessage( -1);
   67                 }
   68                 else
   69                 {
   70                         buf1= new char[1024];
   71                         if (!buf1)
   72                         {
   73                                 MessageBox("Fehler bei Speicherreservierung", "TAutomaticAngleControlDlg", MBSTOP);
   74                                 PostQuitMessage( -1);
   75                         }
   76                 }
   77         }
   78 }
   79 
   80 TAutomaticAngleControlDlg::~TAutomaticAngleControlDlg() {
   81         _FREEOBJ(m_lnkTimer);
   82         _FREELIST(status);
   83         _FREELIST(buf);
   84         _FREELIST(buf1);
   85         _FREEOBJ(Transform);
   86 }
   87 
   88 BOOL TAutomaticAngleControlDlg::Dlg_OnInit(HWND hwnd, HWND hwndCtl, LPARAM lParam)
   89 {
   90         // Inhalt des Status-Textfeldes auslesen
   91         GetDlgItemText(GetHandle(), ID_Status, status, nMaxString);
   92 
   93         // Globale Variable für Schreibpflicht in Justagelog
   94         bWriteLogfile= false;
   95 
   96         //Deaktivierung des Abbruchkriteriums Intensitätsdifferenz
   97         bIntensityDiffActive= false;
   98         CheckDlgButton(hwnd, ID_ActivateIntenseDiff, FALSE);
   99         EnableWindow(GetDlgItem(hwnd, ID_TextMaxIntDiff), FALSE);
  100         EnableWindow(GetDlgItem(hwnd, ID_IntenseDifferenz), FALSE);
  101 
  102         // Test, ob Zähler korrekt im Programm initialisiert wurde
  103         if ( !TDetectorManager::DetectorManager().DimAvailable(0) )
  104         {
  105                 strcat(status, "Counterdetektor...fehlt!\r\n");
  106                 // im Fehlerfall wird der START-Button deaktiviert
  107                 EnableWindow(GetDlgItem(hwnd, cm_start_justage), FALSE);
  108         }
  109         else
  110         {
  111                 // verwendeter Zähler für AutoJustage= akt. Zähler aus der Detectorliste
  112                 Sensor= TDetectorManager::DetectorManager().GetDetector();
  113                 strcat(status, "Counterdetektor...ok!\r\n");
  114                 // Sichergehen, dass Zählerfenster offen ist,
  115                 // ansonsten werden die Zählerwerte nicht korrekt eingelesen
  116                 if ( !Sensor->GetCounterWnd() )
  117                 {
  118                         // Zählerfenster öffnen
  119                         (new TCounterWindow(GetMainInstance(), Sensor))->Show(); 
  120                 }
  121         }
  122 
  123         // Test, ob der Antrieb "Beugung fein" vorhanden ist
  124         if ( !mlIsAxisValid(Omega) )
  125         {
  126                 strcat(status, "Beugung fein...fehlt!\r\n");
  127                 // im Fehlerfall wird der START-Button deaktiviert
  128                 EnableWindow(GetDlgItem(hwnd, cm_start_justage), FALSE);
  129         }
  130         else
  131         {
  132                 strcat(status, "Beugung fein...ok!\r\n");
  133                 // Bestimmung der MotorID zum Antrieb Omega (Beugung fein, DF)
  134                 nMotorDF= mlGetIdByName(Omega);
  135         }
  136 
  137         // Test, ob der Antrieb "Tilt" vorhanden ist
  138         if ( !mlIsAxisValid(Psi) )
  139         {
  140                 strcat(status, "Tilt...fehlt!\r\n");
  141                 // im Fehlerfall wird der START-Button deaktiviert
  142                 EnableWindow(GetDlgItem(hwnd, cm_start_justage), FALSE);
  143         }
  144         else
  145         {
  146                 strcat(status, "Tilt...ok!\r\n");
  147                 // MotorID zuweisen
  148                 nMotorTL= mlGetIdByName(Psi);
  149         }
  150 
  151         // Test, ob der Antrieb "Kollimator" vorhanden ist
  152         if ( !mlIsAxisValid(Collimator) )
  153         {
  154                 strcat(status, "Kollimator...fehlt!\r\n");
  155                 // im Fehlerfall wird der START-Button deaktiviert
  156                 EnableWindow(GetDlgItem(hwnd, cm_start_justage), FALSE);
  157         }
  158         else
  159         {
  160                 strcat(status, "Kollimator...ok!\r\n");
  161                 // MotorID zuweisen
  162                 nMotorCC= mlGetIdByName(Collimator);
  163         }
  164 
  165         // Abfragen des Fehlerzustands über (de)aktivierten START-Button
  166         if ( !IsWindowEnabled(GetDlgItem(hwnd, cm_start_justage)) )
  167                 strcat(status, "Fehler: Es sind nicht alle Geräte bereit!\r\n");
  168 
  169         // Statusmeldung in Status-Textfenster schreiben
  170         SetDlgItemText(GetHandle(), ID_Status, status);
  171         return true;
  172 }
  173 
  174 void TAutomaticAngleControlDlg::Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  175 {
  176         unsigned int rc= 0;
  177 
  178         switch ( id )
  179         {
  180                 case ID_Logfile:
  181                         // Setzen o. Löschen der Auswahlbox für die Protokollierung
  182                         rc= IsDlgButtonChecked(GetHandle(), ID_Logfile);
  183                         if(rc == 0)
  184                                 bWriteLogfile= false;
  185                         else
  186                                 bWriteLogfile= true;
  187                         break;
  188 
  189                 case ID_ActivateIntenseDiff:
  190                         // (De)Aktivierung des Parameters Max. Intensitätsdifferenz
  191                         rc= IsDlgButtonChecked(GetHandle(),ID_ActivateIntenseDiff);                     
  192                         if (rc == 0) 
  193                                 bIntensityDiffActive= false;
  194                         else
  195                                 bIntensityDiffActive= true;
  196                         // (De)Aktivierung der entsprechenden Dialogelemente
  197                         EnableWindow(GetDlgItem(hwnd, ID_IntenseDifferenz), bIntensityDiffActive);
  198                         EnableWindow(GetDlgItem(hwnd, ID_TextMaxIntDiff), bIntensityDiffActive);
  199                         break;
  200 
  201                 case cm_start_justage:
  202                         // START-Button deaktivieren
  203                         EnableWindow(GetDlgItem(hwnd, cm_start_justage), FALSE);
  204                         // Mauszeiger in Sanduhr umwandeln
  205                         SetDefaultCursor( IDC_WAIT );
  206                         // Transformationsobjekt erzeugen
  207                         Transform= new TransformationClass;
  208                         m_NextStep.Clear(); NextStep(jpSetParameters, TRUE); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_set_parameters, 0, 0, PostMessage);
  209                         break;
  210 
  211                 case ID_Help:
  212                         // Aufruf der Hilfe
  213                         WinHelp(hwnd, "SPHELP.HLP", HELP_CONTEXT, Help_AutomaticAdjustment);
  214                         break;
  215 
  216                 default: // auch 'Beenden'
  217                         // alle weiteren Nachrichten werden von der Default-Methode verarbeitet
  218                         TModalDlg::Dlg_OnCommand(hwnd, id, hwndCtl, codeNotify);
  219         }
  220 }
  221 
  222 void TAutomaticAngleControlDlg::NextStep ( EJustagePoints aNext, BOOL aStartTimer ) {
  223         m_NextStep.Append(aNext);
  224         if ( aStartTimer ) m_lnkTimer->StartTimer();
  225 }
  226 
  227 void TAutomaticAngleControlDlg::OnTimer ( TBasicTimer *const ) {
  228         m_lnkTimer->StopTimer(); // Abarbeitung abwarten; nicht parallel arbeiten
  229 
  230         if ( m_NextStep.GetCount()==0 ) return;
  231 
  232         SetDefaultCursor( IDC_WAIT );
  233         EJustagePoints act= (EJustagePoints)m_NextStep.GetAt(0);
  234         m_NextStep.Remove(0); // beim nächsten Mal nichts tun
  235         switch ( act ) {
  236                 case jpSetParameters:
  237                         // Wert für die Toleranz des "Goldenen Schnitts" aus Dialog holen
  238                         GetDlgItemText(GetHandle(), ID_Toleranz, buf, 4);
  239                         // Vorzeichen eleminieren
  240                         Transform->toleranz= fabs(atof(buf));
  241                         // Bereichsprüfung, bei Fehler: Defaultwert
  242                         if ( (Transform->toleranz > 1.0) || (Transform->toleranz < 0.1) )
  243                         {
  244                                 // Defaultwert
  245                                 Transform->toleranz= 1.0;
  246                         }
  247                         // Rückschreiben des korrigierten Wertes in den Dialog
  248                         sprintf(buf, "%.1f", Transform->toleranz);
  249                         SetDlgItemText(GetHandle(), ID_Toleranz, buf);
  250 
  251                         // Wert für die Anzahl der Algorithmus-Durchläufe aus Dialog holen
  252                         GetDlgItemText(GetHandle(), ID_Durchlauf, buf, 4);
  253                         // gegen Vorzeichen hilft "abs"
  254                         durchlauf= abs(atoi(buf));
  255                         // Bereichsprüfung, bei Fehler: Defaultwert
  256                         if ( (durchlauf < 1) || (durchlauf > 7) )
  257                         {
  258                                 // Defaultwert
  259                                 durchlauf= 5;
  260                         }
  261                         // Rückschreiben des korrigierten Wertes in den Dialog
  262                         sprintf(buf, "%d", durchlauf);
  263                         SetDlgItemText(GetHandle(), ID_Durchlauf, buf);
  264 
  265                         // Wert für die Intensitätsdifferenz aus Dialog holen
  266                         // Differenz soll auch als Abbruchkriterium dienen
  267                         GetDlgItemText(GetHandle(), ID_IntenseDifferenz, buf, 8);
  268                         // keine negativen Werte akzeptieren
  269                         fIntenseDifferenz= fabs(atof(buf));
  270                         // Bereichsprüfung (untere Schranke)
  271                         if ( fIntenseDifferenz < 1.0 )
  272                         {
  273                                 // Defaultwert
  274                                 fIntenseDifferenz= 5000.0;
  275                         }
  276                         // Bereichsprüfung (obere Schranke)
  277                         if ( fIntenseDifferenz > 10000.0 )
  278                         {
  279                                 // Maximalwert
  280                                 fIntenseDifferenz= 9999.9f;
  281                         }
  282                         // Rückschreiben des korrigierten Wertes in den Dialog
  283                         sprintf(buf, "%.0f", fIntenseDifferenz);
  284                         SetDlgItemText(GetHandle(), ID_IntenseDifferenz, buf);
  285 
  286                         // Werte für die Intervallgrenze von DF aus dem Dialog auslesen
  287                         GetDlgItemText(GetHandle(), ID_DF_Intervall, buf, 8);
  288                         // Vorzeichen abfangen
  289                         MaxDF= fabs(atof(buf));
  290                         // Bereichsprüfung, bei Fehler: Defaultwert
  291                         if ( (MaxDF < 1.0) || (MaxDF > 300.0) )
  292                         {
  293                                 // Defaultwert
  294                                 MaxDF= 50.0;
  295                         }
  296                         // Rückschreiben des korrigierten Wertes in den Dialog
  297                         sprintf(buf, "%.0f", MaxDF);
  298                         SetDlgItemText(GetHandle(), ID_DF_Intervall, buf);
  299 
  300                         // Werte für die Intervallgrenze von TL aus dem Dialog auslesen
  301                         GetDlgItemText(GetHandle(), ID_TL_Intervall, buf, 8);
  302                         // Vorzeichen abfangen
  303                         MaxTL= fabs(atof(buf));
  304                         // Bereichsprüfung, bei Fehler: Defaultwert
  305                         if ( (MaxTL < 1.0) || (MaxTL > 100.0) )
  306                         {
  307                                 // Defaultwert
  308                                 MaxTL= 20.0;
  309                         }
  310                         // Rückschreiben des korrigierten Wertes in den Dialog
  311                         sprintf(buf, "%.0f", MaxTL);
  312                         SetDlgItemText(GetHandle(), ID_TL_Intervall, buf);
  313 
  314                         // Werte für die Intervallgrenze von CC aus dem Dialog auslesen
  315                         GetDlgItemText(GetHandle(), ID_CC_Intervall, buf, 8);
  316                         // Vorzeichen abfangen
  317                         MaxCC= fabs(atof(buf));
  318                         // Bereichsprüfung, bei Fehler: Defaultwert
  319                         if ( (MaxCC < 1.0) || (MaxCC > 500.0) )
  320                         {
  321                                 // Defaultwert
  322                                 MaxCC= 150.0;
  323                         }
  324                         // Rückschreiben des korrigierten Wertes in den Dialog
  325                         sprintf(buf, "%.0f", MaxCC);
  326                         SetDlgItemText(GetHandle(), ID_CC_Intervall, buf);
  327 
  328                         // Werte für die Anzahl der Messungen pro Intensitätsbestimmung
  329                         // aus dem Dialog auslesen
  330                         GetDlgItemText(GetHandle(), ID_MeasureCount, buf , 8);
  331                         // Vorzeichen filtern
  332                         nMeasureCount= fabs(atoi(buf));
  333                         // Bereichsprüfung (untere, obere Grenze)
  334                         if ( nMeasureCount < 1 )
  335                         {
  336                                 nMeasureCount= 1;
  337                         }
  338                         else if ( nMeasureCount > 6 )
  339                         {
  340                                 nMeasureCount= 6;
  341                         }
  342                         // Rückschreiben des korrigierten Wertes in den Dialog
  343                         sprintf(buf, "%d", nMeasureCount);
  344                         SetDlgItemText(GetHandle(), ID_MeasureCount, buf);
  345 
  346                         NextStep(jpInitialize); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_initialize, 0, 0, PostMessage);
  347                         break;
  348 
  349                 case jpInitialize:
  350                         // Initialisierung des Transform-Objektes mit den Achsen-Suchintervallen
  351                         Transform->Initialize(MaxDF, MaxTL, MaxCC);
  352 
  353                         // Softwareschranken für die Maximumsuche bestimmen und abspeichern
  354                         {
  355                                 Wertebereich= Transform->GetOrigPosBorders();
  356                         }
  357                         // Ausgangsintensität auslesen
  358                         // ohne Ausgabe in Logfile [dazu: MeasureIntensity ohne bWriteLogfile]
  359                         if ( bWriteLogfile )
  360                         {
  361                                 bWriteLogfile= false;
  362                                 MaxIntensity.Intensity= Transform->MeasureIntensity(nMeasureCount);
  363                                 bWriteLogfile= true;
  364                         }
  365                         else
  366                                 MaxIntensity.Intensity= Transform->MeasureIntensity(nMeasureCount);
  367 
  368                         // Ausgangspositionen der Antriebe, an der die
  369                         // Anfangsintensität gemessen wurde, abspeichern
  370                         MaxIntensity.TL= Wertebereich.OrigTL;
  371                         MaxIntensity.DF= Wertebereich.OrigDF;
  372                         MaxIntensity.CC= Wertebereich.OrigCC;
  373 
  374                         // LastIntensity wird mit Intensität=0 initialisiert,
  375                         // da noch keine Justage gestartet wurde (Positionen wie MaxIntensity)
  376                         LastIntensity= MaxIntensity;
  377                         LastIntensity.Intensity= 0;
  378 
  379                         // Zeit zur Bestimmung der Justagedauer
  380                         GetLocalTime(&datum);
  381                         GetLocalTime(&zeit);
  382 
  383                         // Infos ins Logfile schreiben
  384                         if (bWriteLogfile)
  385                         {
  386                                 sprintf(buf, "########################################################\n"
  387                                                 "Automatische Justage gestartet: %02i.%02i.%i %2d:%02d:%02d\n"
  388                                                 "########################################################\n"
  389                                                 "Motorpositionen:\n"
  390                                                 "TL: %.2f Min: %.2f Max: %.2f\n"
  391                                                 "DF: %.2f Min: %.2f Max: %.2f\n"
  392                                                 "CC: %.2f Min: %.2f Max: %.2f\n"
  393                                                 "Intensität: %.2f\n",
  394                                                 datum.wDay, datum.wMonth, datum.wYear,
  395                                                 zeit.wHour, zeit.wMinute, zeit.wSecond,
  396                                                 Wertebereich.OrigTL, Wertebereich.MinTL, Wertebereich.MaxTL,
  397                                                 Wertebereich.OrigDF, Wertebereich.MinDF, Wertebereich.MaxDF,
  398                                                 Wertebereich.OrigCC, Wertebereich.MinCC, Wertebereich.MaxCC,
  399                                                 MaxIntensity.Intensity);
  400                                 WriteToJustageLog(buf);
  401                         }
  402 
  403                         // Bestimmung der Justageanfangszeitpunktes (Uhrzeit in Sekunden)
  404                         justageanfang= 3600 * zeit.wHour + 60 * zeit.wMinute + zeit.wSecond;
  405 
  406                         // Status-Textfeld auslesen - nur 72 Zeichen, da bei jeder neuen Justage
  407                         // nur der jeweilige Justagevorgang im Statusfenster erscheinen soll
  408                         GetDlgItemText(GetHandle(), ID_Status, status, 72);
  409                         strcat(status, "\r\nAutomatische Justage gestartet.\r\n");
  410                         SetDlgItemText(GetHandle(), ID_Status, status);
  411 
  412                         // Durchgangszähler für Optimierung
  413                         // dient dazu, gerade und ungerade Durchgänge des Algo zu erfassen,
  414                         // um abhängig davon abwechselnd Tilt oder Kollimator zu optimieren
  415                         count= 0;
  416 
  417                         // Test auf Intensitätsüberschreitung des Detektors
  418                         if (!Transform->bIntensityTooHigh)
  419                         {
  420                                 // normales Vorgehen
  421                                 NextStep(jpChooseAxis); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_choose_axis, 0, 0, PostMessage);
  422                         }
  423                         else
  424                         {
  425                                 // Abbruch der Justage
  426                                 NextStep(jpPostProcessing); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_post_processing, 0);
  427                         }
  428                         break;
  429 
  430                 case jpChooseAxis:
  431                         // Test auf Intensitätsüberschreitung des Detektors
  432                         if (Transform->bIntensityTooHigh)
  433                         {
  434                                 // Abbruch der Justage
  435                                 NextStep(jpPostProcessing); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_post_processing, 0);
  436                                 break;
  437                         }
  438 
  439                         // Ende der Justage ist erreicht bei: count= durchlauf * 2
  440                         // ein Durchlauf des Algorithmus in die Justage von Tilt und Kollimator
  441                         if (count < durchlauf * 2)
  442                         {
  443                                 count++;
  444 
  445                                 {
  446                                         // Setzen der aktuellen Achsen-Suchbereiche
  447                                         // dazu werden die Bereiche gemäß den KS-Transformationen umgerechnet
  448                                         aktWertebereich= Transform->translate_PosBorders();
  449                                 }
  450 
  451                                 //alle ungeraden Durchgänge (count=1,3,5,etc.) wird CC/DF optimiert
  452                                 if (count % 2 == 1)
  453                                 {
  454                                         NextStep(jpOptimizingCC); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_optimizing_CC, 0);
  455                                 }
  456                                 //alle geraden Durchgänge (count=2,4,etc.) wird TL/DF optimiert
  457                                 else
  458                                 {
  459                                         NextStep(jpOptimizingTL); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_optimizing_TL, 0);
  460                                 }
  461                         }
  462                         else
  463                         {
  464                                 // Ende des Algorithmus ist erreicht
  465                                 NextStep(jpPostProcessing); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_post_processing, 0);
  466                         }
  467                         break;
  468 
  469                 case jpOptimizingCC:
  470                         //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  471                         // 2. Teil des Algorithmus (Kollimator/DF)
  472                         //(nach Überlegung & Test bei den Physikern ist die Variante
  473                         // 1. CC/DF
  474                         // 2. TL/DF
  475                         // der ürsprünglichen vorzuziehen) deshalb ist CC/DF am Anfang
  476                         //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  477 
  478                         // Test auf Intensitätsüberschreitung des Detektors
  479                         if (Transform->bIntensityTooHigh)
  480                         {
  481                                 // Abbruch der Justage
  482                                 NextStep(jpPostProcessing); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_post_processing, 0);
  483                                 break;
  484                         }
  485 
  486                         //(z-Achse)=CC: Such-Intervalle für Goldenen Schnitt festlegen
  487                         intervall_li= aktWertebereich.MinCC;
  488                         intervall_re= aktWertebereich.MaxCC;
  489 
  490                         // # Logging #
  491                         if (bWriteLogfile)
  492                                 WriteToJustageLog("----------Optimierung CC:\r\n");
  493 
  494                         // Goldener Schnitt: Optimierung der Z-Achse(CC)
  495                         // step liefert die Anzahl der benötigten Intervallteilungen,
  496                         // intervall_re/li liefern das letzte Optimierungsintervall
  497                         step= Transform->Goldener_Schnitt(Laufachse_Z, intervall_li,
  498                                                                                           intervall_re, nMeasureCount);
  499 
  500                         NextStep(jpOptimizingDF); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_optimizing_DF, 0, 0, PostMessage);
  501                         break;
  502 
  503                 case jpOptimizingTL:
  504                         //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  505                         // 1. Teil des Algorithmus (Tilt/DF)
  506                         // Erklärung, wieso der 1. Teil des Algorithmus an 2. Stelle steht,
  507                         // nachzulesen am Anfang der Justage (2. Teil des Algorithmus)
  508                         //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  509 
  510                         // Test auf Intensitätsüberschreitung des Detektors
  511                         if (Transform->bIntensityTooHigh)
  512                         {
  513                                 // Abbruch der Justage
  514                                 NextStep(jpPostProcessing); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_post_processing, 0);
  515                                 break;
  516                         }
  517 
  518                         //(x-Achse)=TL: Such-Intervalle für Goldenen Schnitt festlegen
  519                         intervall_li= aktWertebereich.MinTL;
  520                         intervall_re= aktWertebereich.MaxTL;
  521 
  522                         //# Logging #
  523                         if (bWriteLogfile)
  524                                 WriteToJustageLog("----------Optimierung TL:\r\n");
  525 
  526                         // Goldener Schnitt: Optimierung der X-Achse(TL)
  527                         // step liefert die Anzahl der benötigten Intervallteilungen,
  528                         // intervall_re/li liefern das letzte Optimierungsintervall
  529                         step= Transform->Goldener_Schnitt(Laufachse_X, intervall_li,
  530                                                                                           intervall_re, nMeasureCount);
  531 
  532                         NextStep(jpOptimizingDF); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_optimizing_DF, 0, 0, PostMessage);
  533                         break;
  534 
  535                 case jpOptimizingDF:
  536                         // Nachregeln mit DF
  537                         //(y-Achse)=DF: Such-Intervalle für Goldenen Schnitt festlegen
  538 
  539                         // Test auf Intensitätsüberschreitung des Detektors
  540                         if (Transform->bIntensityTooHigh)
  541                         {
  542                                 // Abbruch der Justage
  543                                 NextStep(jpPostProcessing); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_post_processing, 0);
  544                                 break;
  545                         }
  546 
  547                         //(y-Achse)=DF: Such-Intervalle für Goldenen Schnitt festlegen
  548                         intervall_li= aktWertebereich.MinDF;
  549                         intervall_re= aktWertebereich.MaxDF;
  550 
  551                         // # Logging #
  552                         if (bWriteLogfile)
  553                                 WriteToJustageLog("------------Nachregeln DF:\r\n");
  554 
  555                         // Goldener Schnitt: Optimierung der Y-Achse(DF)
  556                         // step1 liefert die Anzahl der benötigten Intervallteilungen,
  557                         // intervall_re/li liefern das letzte Optimierungsintervall
  558                         step1= Transform->Goldener_Schnitt(Laufachse_Y, intervall_li,
  559                                                                                                 intervall_re, nMeasureCount);
  560 
  561                         NextStep(jpCalculate); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_calculate, 0, 0, PostMessage);
  562                         break;
  563 
  564                 case jpCalculate:
  565                         // aktuelle Positionen der Antriebe bestimmen, Protokollierung
  566                         // und abspeichern in Positionen von ActIntensity
  567 
  568                         // Test auf Intensitätsüberschreitung des Detektors
  569                         if (Transform->bIntensityTooHigh)
  570                         {
  571                                 // Abbruch der Justage
  572                                 NextStep(jpPostProcessing); //ALT SendMessage(GetHandle(), WM_COMMAND, cm_post_processing, 0);
  573                                 break;
  574                         }
  575 
  576                         mlSetAxis(nMotorTL);
  577                         mGetDistance(fPosition);
  578                         ActIntensity.TL= fPosition;
  579                         // # Logging #
  580                         sprintf(buf, "Reale Positionen: (Durchlauf %.1f von %d)\r\nTL: %.2f",
  581                                         (float)count / 2, durchlauf, fPosition);
  582 
  583                         mlSetAxis(nMotorDF);
  584                         mGetDistance(fPosition);
  585                         ActIntensity.DF= fPosition;
  586                         // # Logging #
  587                         sprintf(buf1, "  DF: %.2f", fPosition);
  588                         strcat(buf, buf1);
  589 
  590                         mlSetAxis(nMotorCC);
  591                         mGetDistance(fPosition);
  592                         ActIntensity.CC= fPosition;
  593                         // # Logging #
  594                         sprintf(buf1, "  CC: %.2f\r\n", fPosition);
  595                         strcat(buf, buf1);
  596 
  597                         // Ausgabe in Statusfenster und LogFile
  598                         GetDlgItemText(GetHandle(), ID_Status, status, nMaxString);
  599                         strcat(status, buf);
  600                         if (bWriteLogfile)
  601                                 WriteToJustageLog(buf);
  602 
  603                         // aktuelle Intensität auslesen und in ActIntensity speichern
  604                         ActIntensity.Intensity= Transform->MeasureIntensity(nMeasureCount);
  605                         // # Logging #
  606                         sprintf(buf, "Intensität: %.2f\r\nSchritte für Suche: %d\r\n",
  607                                         ActIntensity.Intensity, step + step1);
  608 
  609                         // Test, ob neues Intensitätsmaximum erreicht wurde
  610                         if ( ActIntensity.Intensity > MaxIntensity.Intensity )
  611                         {
  612                                 // Falls ja: neue MaximalIntensität merken
  613                                 MaxIntensity= ActIntensity;
  614                                 // Infos fürs Statusfenster
  615                                 sprintf(buf1, " NEUES MAXIMUM GEFUNDEN\r\n");
  616                                 strcat(buf, buf1);
  617                         // wenn Abbruch-Kriterium Intensitätsdifferenz existiert
  618                         } else if ( bIntensityDiffActive ) {
  619                                 // Test, ob akt. Intensität kleiner als letzte Intensität
  620                                 // dazu: Liegt Abweichung der letzten Intensität (LastIntensity)
  621                                 // von akt. Intensität (ActIntensity) außerhalb des Limits?
  622                                 if ((LastIntensity.Intensity - fIntenseDifferenz) > ActIntensity.Intensity)
  623                                 {
  624                                         // Falls ja: Zurücksetzen der Information der aktuellen Intensität
  625                                         ActIntensity= LastIntensity;
  626                                         // Test, ob absoluter Maximalwert schon früher erreicht wurde
  627                                         if ( LastIntensity.Intensity < MaxIntensity.Intensity )
  628                                         {
  629                                                 // Falls ja: alle Int.Variablen auf max. Intensität setzen
  630                                                 LastIntensity= MaxIntensity;
  631                                                 ActIntensity= MaxIntensity;
  632                                         }
  633 
  634                                         // Zurückfahren der Antriebe an Position mit max. Intensität
  635                                         mlSetAxis(nMotorTL);
  636                                         mMoveToDistance(LastIntensity.TL);
  637                                         while ( !mIsMoveFinish() ) ProcessMessages(1)/* wait until finish */;
  638                                                         
  639                                         mlSetAxis(nMotorDF);
  640                                         mMoveToDistance(LastIntensity.DF);
  641                                         while ( !mIsMoveFinish() ) ProcessMessages(1)/* wait until finish */;
  642 
  643                                         mlSetAxis(nMotorCC);
  644                                         mMoveToDistance(LastIntensity.CC);
  645                                         while ( !mIsMoveFinish() ) ProcessMessages(1)/* wait until finish */;
  646 
  647                                         // Abbruchmeldung im Status-Textfeld & Logfile ausgeben
  648                                         sprintf(buf1, "\r\nLetzter Intensitätswert zu niedrig!\r\nAbbruch und Rückkehr zur Maximalpos.\r\nReale Positionen:\r\nTL: %.2f  DF: %.2f  CC: %.2f\r\nIntensität: %.0f\r\n",
  649                                                         LastIntensity.TL, LastIntensity.DF,
  650                                                         LastIntensity.CC, LastIntensity.Intensity);
  651                                         strcat(buf, buf1);
  652                                         strcat(status, buf);
  653                                         SetDlgItemText(GetHandle(), ID_Status, status);
  654 
  655                                         // ins Logfile schreiben
  656                                         if (bWriteLogfile)
  657                                                 WriteToJustageLog(buf);
  658 
  659                                         // Ermittlung der Anzahl der Textzeilen im Status-Textfeld
  660                                         dwStatusZeilen= SendMessage(GetDlgItem(GetHandle(), ID_Status),
  661                                                                                                 EM_GETLINECOUNT, 0, 0L);
  662 
  663                                         // Scrollen des Textes um dwStatusZeilen minus Anzahl neuer Zeilen
  664                                         SendMessage(GetDlgItem(GetHandle(), ID_Status), EM_LINESCROLL, 0,
  665                                                                 dwStatusZeilen - 18L);
  666 
  667                                         // Abbruch des Justagevorgangs (Verlassen der while-Schleife)
  668                                         NextStep(jpPostProcessing); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_post_processing, 0, 0, PostMessage);
  669                                         break;
  670                                 }
  671 
  672                                 // Ansonsten: die alte Intensität mit aktueller überschreiben
  673                                 LastIntensity= ActIntensity;
  674 
  675                         } //Ende von Flagtest bIntensityDiffActive
  676 
  677                         // Ausgabe der erreichten Intensität und ggf. neues Maximum
  678                         strcat(status, buf);
  679                         SetDlgItemText(GetHandle(), ID_Status, status);
  680                         // # Logging #
  681                         if (bWriteLogfile)
  682                                 WriteToJustageLog(buf);
  683 
  684                         // Ermittlung der Anzahl der Textzeilen des Status-Textfeldes
  685                         dwStatusZeilen= SendMessage(GetDlgItem(GetHandle(), ID_Status),
  686                                                                                 EM_GETLINECOUNT, 0, 0L);
  687                         // Scrollen des Textes um dwStatusZeilen Zeilen - Anzahl des neuen Textes
  688                         SendMessage(GetDlgItem(GetHandle(), ID_Status), EM_LINESCROLL, 0,
  689                                                 dwStatusZeilen - 20L);
  690 
  691                         // Durchführung der Koordinatentransformation
  692                         Transform->PosVektor.get_XYZ(x2, y2, z2);
  693 
  694                         // # Logging #
  695                         sprintf(buf, " PosVektor vor KS-Drehung (%.2f,%.2f,%.2f)\n", x2, y2, z2);
  696 
  697                         if (count % 2 == 1)
  698                                 //alle ungeraden Durchgänge KS-Drehung X-Achse
  699                                 Transform->KoordinatenTransformation(Drehachse_X,
  700                                                                                                          Transform->PosVektor);
  701                         else
  702                                 //alle geraden Durchgänge KS-Drehung um Z-Achse
  703                                 Transform->KoordinatenTransformation(Drehachse_Z,
  704                                                                                                          Transform->PosVektor);
  705 
  706                         Transform->PosVektor.get_XYZ(x, y, z);
  707                         sprintf(buf1, " neuer PositionsVektor (%.2f,%.2f,%.2f)\n", x, y, z);
  708                         strcat (buf, buf1);
  709                         // ins Logfile schreiben
  710                         if (bWriteLogfile)
  711                                 WriteToJustageLog(buf);
  712 
  713                         // Protokollierung der Koordinatensystem-Transformation
  714                         Transform->PosVektor= Transform->translate_to_worldpoints(Transform->PosVektor);
  715                         Transform->PosVektor.get_XYZ(x2, y2, z2);
  716                         sprintf(buf, " PosVektor in Weltkoord. (%.2f,%.2f,%.2f)\n", x2, y2, z2);
  717                         Transform->PosVektor= Transform->translate_from_worldpoints(Transform->PosVektor);
  718                         Transform->PosVektor.get_XYZ(x2, y2, z2);
  719                         sprintf(buf1, " PosVektor im letzten KS (%.2f,%.2f,%.2f)\n", x2, y2, z2);
  720                         strcat (buf, buf1);
  721                         // ins Logfile schreiben
  722                         if (bWriteLogfile)
  723                                 WriteToJustageLog(buf);
  724 
  725                         NextStep(jpChooseAxis); //ALT FORWARD_WM_COMMAND(GetHandle(), cm_choose_axis, 0, 0, PostMessage);
  726                         break;
  727 
  728                 case jpPostProcessing:
  729                         // Statusfenster auslesen
  730                         GetDlgItemText(GetHandle(), ID_Status, status, nMaxString);
  731 
  732                         // Ende der Justage und Test ob eine Verbesserung gegenüber dem
  733                         // vor der Justage eingestellten Wert erreicht wurde
  734                         // aktueller Intensitätswert < absolutes Maximum ?
  735                         // Toleranz 1 Prozent (kleine Messungenauigkeiten ausbügeln)
  736                         if (ActIntensity.Intensity + (0.01*MaxIntensity.Intensity) < MaxIntensity.Intensity)
  737                         {
  738                                 // falls ja: Zurückfahren der Antriebe an Position mit max. Intensity
  739                                 mlSetAxis(nMotorTL);
  740                                 mMoveToDistance(MaxIntensity.TL);
  741                                 while (!mIsMoveFinish())
  742                                         ProcessMessages(1)/* wait until finish */;
  743                                 mlSetAxis(nMotorDF);
  744                                 mMoveToDistance(MaxIntensity.DF);
  745                                 while (!mIsMoveFinish())
  746                                         ProcessMessages(1)/* wait until finish */;
  747                                 mlSetAxis(nMotorCC);
  748                                 mMoveToDistance(MaxIntensity.CC);
  749                                 while (!mIsMoveFinish())
  750                                         ProcessMessages(1)/* wait until finish */;
  751 
  752                                 // Infos ins Statusfenster
  753                                 sprintf(buf, "\r\nRückkehr zur Maximumposition...\r\nReale Positionen:\r\nTL: %.2f  DF: %.2f  CC: %.2f\r\nIntensität: %.0f\r\n",
  754                                                 MaxIntensity.TL, MaxIntensity.DF, MaxIntensity.CC, MaxIntensity.Intensity);
  755                                 strcat(status, buf);
  756                                 // ins Logfile schreiben
  757                                 if (bWriteLogfile)
  758                                         WriteToJustageLog(buf);
  759                         }
  760 
  761                         // Test auf Intensitätsüberschreitung des Detektors
  762                         if (!Transform->bIntensityTooHigh)
  763                         {
  764                                 // falls kein Überlauf stattfand:
  765                                 // Nachregelung für Achse DF
  766 
  767                                 sprintf(buf, "\r\nIntensitätskorrektur für Antrieb DF...\r\n");
  768                                 strcat(status, buf);
  769                                 // ins Statusfenster & Logfile schreiben
  770                                 SetDlgItemText(GetHandle(), ID_Status, status);
  771                                 if (bWriteLogfile)
  772                                         WriteToJustageLog(buf);
  773 
  774                                 Transform->DFCorrection(nMeasureCount, MaxIntensity.DF, MaxIntensity.Intensity);
  775 
  776                                 sprintf(buf, "Korrektur: DF:%.2f Intensität:%.0f\r\n\r\n",
  777                                                 MaxIntensity.DF, MaxIntensity.Intensity);
  778                         }
  779                         else
  780                                 sprintf(buf, "\r\nJustage wurde wegen Überschreitung \r\nder maximal zulässigen Detektorintensität \r\nabgebrochen. \r\nBitte vermindern Sie die Spannung \r\ndes Röntgenstrahlgenerators.\r\n\r\n");
  781 
  782                         // Berechnung der Justagedauer
  783                         GetLocalTime(&datum);
  784                         GetLocalTime(&zeit);
  785                         justageende= 3600 * zeit.wHour + 60 * zeit.wMinute + zeit.wSecond;
  786                         justagezeit= justageende - justageanfang;
  787                         sprintf(buf1, "Dauer der Justage: %02d:%02d.%02d\r\n",
  788                                         justagezeit / 3600, (justagezeit % 3600) / 60, (justagezeit % 3600) % 60);
  789                         strcat(buf, buf1);
  790                         strcat(status, buf);
  791                         // Ins Statusfenster schreiben
  792                         SetDlgItemText(GetHandle(), ID_Status, status);
  793                         // geschriebene Zeilen im Statusfenster ermitteln
  794                         dwStatusZeilen= SendMessage(GetDlgItem(GetHandle(), ID_Status),
  795                                                                                 EM_GETLINECOUNT, 0, 0L);
  796                         // entprechend den Scrollbar einstellen, dass das Textende zu sehen ist
  797                         SendMessage(GetDlgItem(GetHandle(), ID_Status), EM_LINESCROLL, 0,
  798                                                 dwStatusZeilen - 18L);
  799 
  800                         // Logdaten ins Logfile schreiben
  801                         if (bWriteLogfile)
  802                         {
  803                                 sprintf(buf1, "########################################################\nAutomatische Justage beendet: %02i.%02i.%i %2d:%02d:%02d\n########################################################\r\n",
  804                                                 datum.wDay, datum.wMonth, datum.wYear,
  805                                                 zeit.wHour, zeit.wMinute, zeit.wSecond);
  806                                 // erst noch die Dauer rausschreiben
  807                                 strcat(buf, buf1);
  808                                 WriteToJustageLog(buf);
  809                         }
  810 
  811                         // Transformationsobjekt zerstören
  812                         _FREEOBJ(Transform);
  813 
  814                         SetInfo("Automatische Justage abgeschlossen ...");
  815 
  816                         // Start-Button aktivieren
  817                         EnableWindow(GetDlgItem(GetHandle(), cm_start_justage), TRUE);
  818 
  819                         // Maus-Sanduhr in Zeiger umwandeln
  820                         SetDefaultCursor( IDC_ARROW );
  821                         // Justage beendet
  822                         break;
  823         }
  824         if ( m_NextStep.GetCount() && act!=jpPostProcessing ) { // jetzt erst den nächsten Schritt
  825                 m_lnkTimer->StartTimer(); 
  826                 SetDefaultCursor( IDC_WAIT );
  827         } else SetDefaultCursor( IDC_ARROW ); // fertig
  828 }
  829 
  830 void TAutomaticAngleControlDlg::LeaveDialog(void)
  831 {
  832         // Text in Programmstatuszeile schreiben
  833         SetInfo("Automatische Justage verlassen...");
  834 
  835         m_NextStep.Clear();
  836         NextStep(jpPostProcessing);
  837         
  838         // Detektor initialisieren
  839         Sensor->MeasureStop();
  840         Sensor->PopSettings();
  841         Sensor->MeasureStart();
  842 
  843         // Motoren anhalten
  844         mStopDrive(TRUE);
  845 }
  846