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