source: trunk/MagicSoft/Cosy/main/MCosy.cc@ 7041

Last change on this file since 7041 was 6841, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 39.5 KB
Line 
1#include "MCosy.h"
2
3#include <iomanip.h>
4#include <fstream.h>
5#include <iostream.h>
6
7#include <TROOT.h>
8#include <TEnv.h>
9#include <TSystem.h>
10#include <TApplication.h>
11#include <TTimer.h>
12
13#include <TH2.h>
14#include <TH3.h>
15#include <TProfile.h>
16#include <TCanvas.h>
17
18#include "MGCosy.h"
19#include "MTime.h"
20#include "MDriveCom.h"
21#include "MStarguider.h"
22#include "SlaStars.h"
23#include "MPointing.h"
24#include "MTracking.h"
25
26#include "slalib/slalib.h" // FIXME: REMOVE
27
28#include "macs.h"
29#include "shaftencoder.h"
30
31ClassImp(MCosy);
32
33typedef struct tm tm_t;
34
35/* +===================================+
36 FIXME: What if fMac3 (Sync) died?
37 +===================================+
38*/
39
40//#define EXPERT
41#undef EXPERT
42
43/*
44ZdAz MCosy::CorrectTarget(const ZdAz &src, const ZdAz &dst)
45{
46 // CorrectTarget [se]
47
48 // src [se]
49 // dst [rad]
50
51 // fAltMax = 70
52 // fAltMin = -105/110
53 // fAzMin = -355
54 // fAzMax = 355
55
56 ZdAz source = src * 360.0/16384.0;
57 ZdAz dest = dst * kRad2Deg;
58
59 if (dest.Zd()>-3 && dest.Zd()<3)
60 dest.Zd(dest.Zd()<0?-3:3);
61
62 if (dest.Zd()>-1e-6 && dest.Zd()<1e-6)
63 return dst*(16384.0/k2Pi);
64
65 const float fZdMin = -67;
66 const float fZdMax = 67;
67 const float fAzMin = -29;
68 const float fAzMax = 423;
69
70 //
71 // This corrects to target for the shortest distance, not for the fastest move!
72 //
73 ZdAz s = source-dest;
74
75 float min = s.Sqr();
76
77 //
78 // Is it enought to search inside one revolution?
79 //
80 ZdAz ret = dest;
81
82 for (int i=-5; i<5+1; i++)
83 {
84 const ZdAz p(i%2 ? -dest.Zd() : dest.Zd(), dest.Az() - i*180);
85
86 //
87 // Range Check
88 //
89 if (p.Zd()<fZdMin || p.Zd()>fZdMax)
90 continue;
91
92 if (p.Az()<fAzMin || p.Az()>fAzMax)
93 continue;
94
95 //
96 // Calculate distance
97 //
98 s = source-p;
99
100 const float dist = s.Sqr();
101
102 if (dist > min)
103 continue;
104
105 //
106 // New shortest distance
107 //
108 ret = p;
109 min = dist;
110 }
111 return ret*(16384.0/360.0);
112}
113*/
114
115// --------------------------------------------------------------------------
116//
117// GetSePos, reads the Shaftencoder positions from the Can-drivers
118// for the shaftencoders. The two shaft encoders at the elevation axis
119// are avaraged. The values are returned as a ZdAz object.
120//
121// If one of the two shaftencoders on the elevation axis is missing
122// the other one's position is returned.
123//
124// The positions are alway up-to-date because the shaftencoders are
125// sending all changes immediatly.
126//
127ZdAz MCosy::GetSePos() const
128{
129 const int pa = fAz->GetPos();
130 if (fZd1->IsZombieNode() && fZd2->IsZombieNode())
131 return ZdAz(0, pa);
132
133 //
134 // Get the values
135 //
136 int p1 = (fZd1->GetPos()+8192)%16384;
137 int p2 = -(fZd2->GetPos()+8192)%16384;
138
139 if (fZd1->IsZombieNode())
140 return ZdAz(p2, pa);
141 if (fZd2->IsZombieNode())
142 return ZdAz(p1, pa);
143
144 //
145 // interpolate shaft encoder positions
146 //
147 float p = (float)(p1+p2)/2;
148
149 return ZdAz(p, pa);
150}
151
152// --------------------------------------------------------------------------
153//
154// reads the Rotary encoder positions from the last request of the Macs.
155//
156// The positions are returned as a ZdAz object. Use RequestRePos to request
157// the current positions first.
158//
159ZdAz MCosy::GetRePos()
160{
161 return ZdAz(fMac2->GetPos(), fMac1->GetPos());
162}
163
164// --------------------------------------------------------------------------
165//
166// reads the Rotary encoder positions from the Macs.
167//
168// The positions are returned as a ZdAz object. The positions are the ones
169// which are send as PDOs to the computer. This is done at a given
170// frequency. Which means, that this positions are not ought to be
171// up-to-date.
172//
173ZdAz MCosy::GetRePosPdo()
174{
175 return ZdAz(fMac2->GetPdoPos(), fMac1->GetPdoPos());
176}
177
178// --------------------------------------------------------------------------
179//
180// check for a break-signal (from the msgqueue) and errors.
181//
182int MCosy::StopWaitingForSDO() const
183{
184 return 0/*Break() || HasError()*/;
185}
186
187// --------------------------------------------------------------------------
188//
189// Waits for a movement to become finished.
190//
191// First waits for all peding Sdos, then waits until both motors are stopped
192// or waiting for SDOs was stopped (either by an error or by Break)
193//
194void MCosy::WaitForEndMovement()
195{
196 // FIXME, what when waiting times out (Zombie)
197 if (!fMac1 || !fMac2)
198 return;
199
200 while ((fMac1->IsPositioning() || fMac2->IsPositioning()) &&
201 !(Break() || HasError() || HasZombie()))
202 usleep(1);
203
204 if (!Break() && !HasError() && !HasZombie())
205 return;
206
207 MTime t(-1);
208 lout << t << " - MCosy::WaitForEndMovement aborted...";
209 if (Break())
210 lout << " Break signal...";
211 if (HasError())
212 lout << " Network has error...";
213 if (HasZombie())
214 lout << " Network has zombie...";
215 lout << endl;
216}
217
218// --------------------------------------------------------------------------
219//
220// Check for an error...
221//
222// This is ment for usage after the Action: All Motors Stop.
223//
224void MCosy::CheckForError()
225{
226 //
227 // Check all Can-Nodes for an Error. If there is no error the motor
228 // status is set to stopped.
229 //
230 if (HasError() || HasZombie())
231 {
232 SetStatus(MDriveCom::kError);
233 return;
234 }
235
236 if (fMac1->IsPositioning() || fMac2->IsPositioning())
237 SetStatus(MDriveCom::kMoving);
238 else
239 SetStatus(MDriveCom::kStopped);
240
241 //
242 // If there is an error, the error status is set to Error.
243 //
244
245 /*
246 FIXME: HANDLINGE ERROR
247
248 //
249 // Now try to handle the error.
250 //
251 fMac1->HandleError();
252 fMac2->HandleError();
253
254 //
255 // If the error couldn't get solved return
256 //
257 if (HasError())
258 return;
259
260 //
261 // Set motor status to stopped
262 //
263 SetStatus(MDriveCom::kStopped);
264 */
265}
266
267Bool_t MCosy::CheckRange(const ZdAz &d) const
268{
269 // d [rad]
270
271 if (d.Zd()<fMin.Zd())
272 {
273 lout << "ERROR: Requested Zenith Angle below negative endswitch." << endl;
274 return kFALSE;
275 }
276
277 if (d.Zd()>fMax.Zd())
278 {
279 lout << "ERROR: Requested Zenith Angle behind positive endswitch." << endl;
280 return kFALSE;
281 }
282
283 if (d.Az()<fMin.Az())
284 {
285 lout << "ERROR: Requested Azimuth Angle below negative endswitch." << endl;
286 return kFALSE;
287 }
288
289 if (d.Az()>fMax.Az())
290 {
291 lout << "ERROR: Requested Azimuth Angle behind positive endswitch." << endl;
292 return kFALSE;
293 }
294
295
296 return kTRUE;
297}
298
299ZdAz MCosy::AlignTrackingPos(ZdAz pointing) const
300{
301 // pointing [rad]
302 // AlignTrackingPos [deg]
303
304 pointing *= kRad2Deg;
305
306 if (pointing.Zd()<0)
307 {
308 pointing.Zd(-pointing.Zd());
309 pointing.Az(pointing.Az()+180);
310 //lout << "ZD=-ZD Az+=180" << endl;
311 }
312
313 const ZdAz se = GetSePos()*TMath::TwoPi()/kResSE; // [rad]
314 const ZdAz unbendedse = fBending.CorrectBack(se)*kRad2Deg; // ist pointing
315
316 //lout << "Unbended: " << unbendedse.Zd() << " " << unbendedse.Az() << endl;
317
318 do
319 {
320 const Double_t d = unbendedse.Az() - pointing.Az();
321 if (d>-180 && d<=180)
322 break;
323
324 //lout << "AZ += " << TMath::Sign(360., d) << endl;
325
326 pointing.Az(pointing.Az()+TMath::Sign(360., d));
327 } while (1);
328
329 return pointing/kRad2Deg;
330/*
331 const Bool_t rc = CheckRange(pointing);
332 za = pointing/kRad2Deg; // [rad]
333
334 if (!rc)
335 lout << "Error: Aligned position out of Range." << endl;
336
337 return rc;*/
338}
339
340Double_t MCosy::Starguider(Double_t mjd, ZdAz &dest) const
341{
342 ifstream fin("pointingpos.txt");
343 if (!fin)
344 return -1;
345
346 Double_t mjd0, zd, az;
347 fin >> mjd0 >> zd >> az;
348
349 mjd0 += 52000;
350
351 if (mjd0+1./24/60 <mjd)
352 return -1;
353
354 ZdAz point=AlignTrackingPos(ZdAz(zd, az)/kRad2Deg);
355 /*
356 if (!AlignTrackingPos(ZdAz(zd, az), point))
357 {
358 cout << "Starguider position couldn't be aligned..." << endl;
359 return -1;
360 }*/
361
362 // FIXME: Check Range missing!
363
364 const ZdAz diff = (dest-point)*kRad2Deg;
365
366 if (diff.Zd()>5 || diff.Az()>5)
367 {
368 cout << "Starguider deviation too large... dZd=" << diff.Zd() <<" dAz="<<diff.Az() << endl;
369 return -1;
370 }
371
372 dest -= point;
373 dest *= -kGearTot/TMath::TwoPi(); // [re]
374
375 cout << "Using Starguider... dZd=" << dest.Zd() << " dAz=" << dest.Az() << endl;
376
377 return (mjd-mjd0) * (24*60*60); // [s]
378}
379
380// --------------------------------------------------------------------------
381//
382// Move the telescope to the given position. The position must be given in
383// a ZdAz object in rad.
384//
385// The first positioning is done absolutely. If we didn't reach the
386// correct psotion we try to correct for this by 10 relative position
387// maneuvers. If this doesn't help positioning failed.
388//
389// As a reference the shaftencoder values are used.
390//
391int MCosy::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
392{
393 MPointing point(this, lout);
394
395//#ifdef EXPERT
396// point.SetAccDec(0.4, 0.4);
397// point.SetVelocity(0.2); // fast: 0.6, slow: 0.2
398//#else
399 point.SetPointAccDec(0.2, 0.1);
400 point.SetPointVelocity(0.1);
401//#endif
402
403 return point.SetPosition(dst, track);
404}
405
406void MCosy::SetTrackingPosRE(ZdAz za)
407{
408 za /= kGearTot; // [U_tel]
409 za *= TMath::TwoPi(); // [rad]
410 //cout << "RE1: " << za.Zd()*180/3.1415 << " " << za.Az()*180/3.1415 << endl;
411 fTrackingPosRaw = za*TMath::RadToDeg();
412 fTrackingPos = fBending.CorrectBack(za)*TMath::RadToDeg();
413 //cout << "RE2: " << fTrackingPos.Zd() << " " << fTrackingPos.Az() << endl;
414}
415
416void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
417{
418 MTracking track(this, lout);
419 track.SetOut(fOutRep);
420//#ifdef EXPERT
421// track.SetPointAccDec(0.4, 0.4);
422// track.SetPointVelocity(0.2); // fast: 0.6, slow: 0.2
423//#else
424 track.SetPointAccDec(0.2, 0.1);
425 track.SetPointVelocity(0.1);
426//#endif
427 track.SetTrackAccDec(0.1, 0.1);
428
429 track.TrackPosition(dst);
430}
431
432void MCosy::TrackPositionGRB(const RaDec &dst) // ra, dec [rad]
433{
434 MTracking track(this, lout);
435 track.SetOut(fOutRep);
436//#ifdef EXPERT
437// track.SetPointAccDec(0.4, 0.4);
438// track.SetPointVelocity(0.2); // fast: 0.6, slow: 0.2
439//#else
440 track.SetPointAccDec(0.2, 0.1);
441 track.SetPointVelocity(0.1);
442//#endif
443 track.SetTrackAccDec(0.1, 0.1);
444
445 track.TrackPosition(dst);
446}
447
448// --------------------------------------------------------------------------
449//
450// Stops the movement of both motors.
451//
452// Sets the status to stopping. Sets the deceleration to 50% of the maximum.
453// stops. Quits the revolution mode and wait for the end of the movement.
454//
455void MCosy::StopMovement()
456{
457 //
458 // Set status to Stopping
459 //
460 SetStatus(MDriveCom::kStopping);
461
462 //
463 // set deceleration to 50%
464 //
465 cout << "Stopping movement (dec=30%)..." << endl;
466 if (fMac1 && fMac2)
467 {
468#ifdef EXPERT
469 fMac1->SetDeceleration(0.5*fMac1->GetVelRes());
470 fMac2->SetDeceleration(0.5*fMac2->GetVelRes());
471#else
472 fMac1->SetDeceleration(0.3*fMac1->GetVelRes());
473 fMac2->SetDeceleration(0.3*fMac2->GetVelRes());
474#endif
475 fMac1->SetRpmMode(FALSE);
476 fMac2->SetRpmMode(FALSE);
477 }
478
479/*
480 fMac1->SetDeceleration(0.3*fMac1->GetVelRes());
481 fMac2->SetDeceleration(0.3*fMac2->GetVelRes());
482
483 fMac2->SendSDO(0x3000, Macs::string('s','t','o','p'));
484 fMac1->SendSDO(0x3000, Macs::string('s','t','o','p'));
485 fMac2->WaitForSdo(0x3000, 0);
486 fMac1->WaitForSdo(0x3000, 0);
487 fMac1->SetRpmMode(FALSE);
488 fMac2->SetRpmMode(FALSE);
489 */
490
491 //
492 // Wait for the movement to really be finished.
493 //
494#ifdef EXPERT
495 cout << "Waiting for end of movement..." << endl;
496#endif
497 WaitForEndMovement();
498
499 //
500 // Check whether everything works fine.
501 //
502 CheckForError();
503#ifdef EXPERT
504 cout << "Movement stopped." << endl;
505#endif
506}
507
508bool MCosy::CheckNetwork()
509{
510 //return kTRUE;
511 //CheckConnections();
512
513 CheckForError();
514
515 if (HasZombie())
516 {
517 lout << "- Found Zombies in Network..." << endl;
518 if (!RebootZombies())
519 return false;
520 }
521
522 /*
523 FIXME HANDLING ERROR
524 */
525 if (HasError())
526 {
527 fMac1->HandleError();
528 fMac2->HandleError();
529 fMac3->HandleError();
530 if (HasError() || HasZombie())
531 return false;
532 }
533
534 CheckForError();
535 return true;
536}
537
538void *MCosy::Proc(int msg, void *mp)
539{
540 switch (msg)
541 {
542 case WM_WAIT:
543 cout << "Wait for execution of Proc(WM_*, ): done." << endl;
544 return NULL;
545
546 case WM_STOP:
547 //cout << "MCosy::Proc: Stop." << endl;
548 if (!CheckNetwork())
549 return (void*)0xebb0;
550 StopMovement();
551 return NULL;
552/*
553 case WM_PRESET:
554 cout << "WM_Preset: start." << endl;
555 if (!CheckNetwork())
556 return (void*)0xebb0;
557 fZd1->SetPreset();
558 fZd2->SetPreset();
559 fAz->SetPreset();
560 cout << "WM_Preset: done. (return 0xaffe)" << endl;
561 return (void*)0xaffe;
562*/
563 /*
564 case WM_CALIB:
565 {
566 cout << "WM_Calib: start." << endl;
567 if (!CheckNetwork())
568 return (void*)0xebb0;
569
570 SlaStars sla(fObservatory);
571 sla.Now();
572
573 RaDec rd = *((RaDec*)mp);
574
575 //RaDec rd(37.94, 89.2644); // POLARIS
576 //RaDec rd(213.915417, 19.1825); // ARCTURUS
577
578 cout << "Calibrating to: " << rd.Ra()*24/360 << "h " << rd.Dec() << "°" << endl;
579
580 ZdAz za=sla.CalcZdAz(rd*kDeg2Rad)*16384.0/k2Pi;
581
582 cout << "Calc Zd: " << za.Zd() << " Az: " << za.Az() << endl;
583
584 ZdAz sepos = GetSePos();
585 cout << "Got Zd: " << sepos.Zd() << " Az: " << sepos.Az() << endl;
586
587 fZd1->SetPreset(za.Zd());
588 fZd2->SetPreset(-za.Zd());
589 fAz->SetPreset(za.Az());
590
591 cout << "WM_Calib: done. (return 0xaffe)" << endl;
592 }
593 return (void*)0xaffe;
594 */
595 case WM_TPOINT:
596 {
597 //cout << "WM_TPoint: start." << endl;
598 SlaStars sla(fObservatory);
599 sla.Now();
600
601 RaDec rd = *((RaDec*)mp);
602 cout << "TPoint Star: " << rd.Ra()/15 << "h " << rd.Dec() << "°" << endl;
603
604 AltAz za=sla.CalcAltAz(rd*kDeg2Rad)*kRad2Deg;
605
606 if (!fOutTp)
607 {
608 //
609 // open tpoint file
610 //
611 const TString name = GetFileName("tpoint/tpoint_%s.txt");
612 cout << "TPoint-Cosy File ********* " << name << " ********** " << endl;
613
614 fOutTp = new ofstream(name);
615 *fOutTp << "Magic Model TPOINT data file" << endl;
616 *fOutTp << ": ALTAZ" << endl;
617 *fOutTp << "49 48 0 ";
618 *fOutTp << sla.GetTime().Year() << " " << sla.GetTime().Month() << " " << sla.GetTime().Day() << " ";
619 *fOutTp << /*"20 1013.25 300 0.5 0.55 0.0065" <<*/ endl;
620 // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
621 }
622
623 cout << " Alt/Az: " << za.Alt() << "° " << za.Az() << "°" << endl;
624 *fOutTp << setprecision(7) << za.Az() << " " << za.Alt() << " ";
625
626 ZdAz sepos = GetSePos()*TMath::TwoPi()/kResSE;
627 za.Set(TMath::Pi()/2-sepos.Zd(), sepos.Az());
628 za *= kRad2Deg;
629
630 cout << " SE-Pos: " << za.Alt() << "° " << za.Az() << "°" << endl;
631 *fOutTp << fmod(za.Az()+360, 360) << " " << za.Alt() << " ";
632
633 if (fStarguider)
634 {
635 XY tp = fStarguider->GetCoordinates();
636 *fOutTp << 90-tp.X() << " " << tp.Y() << " ";
637 }
638
639 *fOutTp << rd.Ra()/15 << " " << rd.Dec() << " " << setprecision(11) << sla.GetMjd() << endl;
640
641 //cout << "WM_TPoint: done. (return 0xaffe)" << endl;
642 }
643 return (void*)0xca1b;
644
645 case WM_TRACKPOS:
646 //cout << "WM_TrackPosition: start." << endl;
647 {
648 if (!CheckNetwork())
649 return (void*)0xebb0;
650
651 ZdAz dest = *((ZdAz*)mp) * kDeg2Rad;
652 if (!SetPosition(dest))
653 return (void*)0x1234;
654
655 SlaStars sla(fObservatory);
656 sla.Now();
657
658 RaDec rd = sla.CalcRaDec(dest);
659 TrackPosition(rd);
660 }
661 //cout << "WM_TrackPosition: done. (return 0xabcd)" << endl;
662 return (void*)0xabcd;
663
664 case WM_POSITION:
665 //cout << "WM_Position: start." << endl;
666 {
667 if (!CheckNetwork())
668 return (void*)0xebb0;
669
670 ZdAz dest = *((ZdAz*)mp);
671 SetPosition(dest*kDeg2Rad);
672 }
673 //cout << "WM_Position: done. (return 0x7777)" << endl;
674 return (void*)0x7777;
675
676 case WM_POSITION1:
677 //cout << "WM_Position1: start." << endl;
678 {
679 if (!CheckNetwork())
680 return (void*)0xebb0;
681
682 ZdAz dest = *((ZdAz*)mp);
683 SetPosition(dest*kDeg2Rad, kTRUE);
684 }
685 //cout << "WM_Position: done. (return 0x7777)" << endl;
686 return (void*)0x7777;
687
688 case WM_TESTSE:
689 //cout << "WM_TestSe: start." << endl;
690 fBackground = mp ? kBgdSeTest : kBgdNone;
691 //cout << "WM_TestSe: done. (return 0x1e51)" << endl;
692 return (void*)0x1e51;
693
694 case WM_GEAR:
695 //cout << "WM_Gear: start." << endl;
696 fBackground = mp ? kBgdGear : kBgdNone;
697 //cout << "WM_Gear: done. (return 0xfeaf)" << endl;
698 return (void*)0xfeaf;
699
700 case WM_DISPLAY:
701 //cout << "WM_Display: start." << endl;
702 fTriggerDisplay = kTRUE;
703 //cout << "WM_Disply: done. (return 0xd1e1)" << endl;
704 return (void*)0xd1e1;
705
706 case WM_TRACK:
707 //cout << "WM_Track: START" << endl;
708 {
709 RaDec dest = ((RaDec*)mp)[0];
710 if (fStarguider)
711 fStarguider->SetPointingPosition(((RaDec*)mp)[1]);
712 if (!CheckNetwork())
713 return (void*)0xebb0;
714 TrackPosition(dest*kDeg2Rad);
715 }
716 //cout << "WM_Track: done. (return 0x8888)" << endl;
717 return (void*)0x8888;
718
719 case WM_GRB:
720 //cout << "WM_Track: START" << endl;
721 {
722 RaDec dest = ((RaDec*)mp)[0];
723 if (fStarguider)
724 fStarguider->SetPointingPosition(((RaDec*)mp)[1]);
725 if (!CheckNetwork())
726 return (void*)0xebb0;
727 TrackPositionGRB(dest*kDeg2Rad);
728 }
729 //cout << "WM_Track: done. (return 0x8888)" << endl;
730 return (void*)0x8888;
731
732 case WM_NEWTRACK:
733 //cout << "WM_NewTrack: START" << endl;
734 fRaDec = *((RaDec*)mp);
735 //cout << "WM_NewTrack: done. (return 0x9999)" << endl;
736 return (void*)0x9999;
737
738 case WM_LOADBENDING:
739 //cout << "WM_LoadBending: START" << endl;
740 fBending.Load("bending.txt");
741 //cout << "WM_LoadBending: done. (return 0xbe0d)" << endl;
742 return (void*)0xbe0d;
743
744 case WM_RESETBENDING:
745 //cout << "WM_ResetBending: START" << endl;
746 fBending.Reset();
747 //cout << "WM_ResetBending: done. (return 0xbe0e)" << endl;
748 return (void*)0xbe0e;
749
750 case WM_HOME:
751 //cout << "WM_Home: START" << endl;
752 if (!CheckNetwork())
753 return (void*)0xebb0;
754 else
755 {
756 cout << "HOME NOT ALLOWED... for Magic." << endl;
757 /*
758 cout << "Going Home..." << endl;
759 TEnv env(".cosyrc");
760
761 SetStatus(MDriveCom::kMoving);
762
763 fMac1->SetHome(250000, env.GetValue("Az_MaxTime2ReachHome[s]", 100));
764 fMac2->SetHome(250000, env.GetValue("Zd_MaxTime2ReachHome[s]", 100));
765
766 lout << "SETHOME DONE" << endl;
767
768 SetStatus(HasError() ? MDriveCom::kError : MDriveCom::kStopped);
769
770 fAz->SetPreset();
771 fZd1->SetPreset();
772 fZd2->SetPreset();
773
774 fMac1->ReqPos();
775 fMac2->ReqPos();
776 fMac3->StopMotor();
777 */
778 }
779 //cout << "WM_Home: done. (return 0x403e)" << endl;
780 return (void*)0x403e;
781
782 case WM_CALCALTAZ:
783 {
784 cout << endl;
785
786 SlaStars sla(fObservatory);
787 sla.Now();
788
789 XY xy = *((XY*)mp);
790 RaDec rd(xy.X()*15., xy.Y()); // [deg]
791
792 ZdAz a1 = sla.CalcZdAz(rd*kDeg2Rad); // [rad]
793
794 cout << "Ra/Dec source: " << xy.X() << "h " << xy.Y() << "°" << endl;
795 cout << "Zd/Az target: " << a1.Zd()*kRad2Deg << "° " << a1.Az()*kRad2Deg << "°" << endl;
796
797 if (fZd1 && fZd2 && fAz)
798 a1 = AlignTrackingPos(a1);
799
800 a1 = fBending(a1);
801 CheckRange(a1);
802 a1 *= kRad2Deg;
803
804 const ZdAz a2 = a1*kResSE/360;
805
806 cout << "Zd/Az bended: " << a1.Zd() << "° " << a1.Az() << "°" << endl;
807 cout << "SE bended: " << a2.Zd() << " " << a2.Az() << endl;
808 }
809 return (void*)0xa17a;
810
811 case WM_ENDSWITCH:
812 {
813 ZdAz pos = GetSePos()*TMath::TwoPi()/kResSE;
814 pos = fBending.SubtractOffsets(pos)*kRad2Deg;
815
816 cout << "Endswitch Position: Zd=" << pos.Zd() << "° Az=";
817 cout << pos.Az() << "°" << endl;
818 }
819
820 return (void*)0x1010;
821
822 case WM_QUIT:
823 cout << "WM_Quit: now." << endl;
824 if (!CheckNetwork())
825 {
826 lout << "ERROR: Cannot shutdown CANbus network." << endl;
827 return (void*)0xebb0;
828 }
829 TerminateApp();
830 cout << "WM_Quit: done." << endl;
831 return (void*)0xaaaa;
832 }
833 cout << "MCosy::Proc: Unknown message 0x" << msg << endl;
834 return (void*)0xffffffff;
835}
836
837void *MTTalk::Thread()
838{
839 fCosy->TalkThread();
840 return NULL;
841}
842
843void MCosy::ReadConfig()
844{
845 cout << "Reading configuration file..." << flush;
846 TEnv env(".cosyrc");
847 cout << "done." << endl;
848
849 cout << "Reading telescope range..." << flush;
850 const Double_t amin = env.GetValue("Az_Min[deg]", -95.0);
851 const Double_t zmin = env.GetValue("Zd_Min[deg]", -75.0);
852 fMin.Set(zmin, amin);
853
854 const Double_t amax = env.GetValue("Az_Max[deg]", 305.0);
855 const Double_t zmax = env.GetValue("Zd_Max[deg]", 98.25);
856 fMax.Set(zmax, amax);
857 cout << "done." << endl;
858
859 cout << " * Min: " << zmin << "deg " << amin << "deg" << endl;
860 cout << " * Max: " << zmax << "deg " << amax << "deg" << endl;
861
862 fMin = fBending.AddOffsets(fMin/kRad2Deg);
863 fMax = fBending.AddOffsets(fMax/kRad2Deg);
864
865 cout << " * Min': " << fMin.Zd()*kRad2Deg << "deg " << fMin.Az()*kRad2Deg << "deg" << endl;
866 cout << " * Max': " << fMax.Zd()*kRad2Deg << "deg " << fMax.Az()*kRad2Deg << "deg" << endl;
867
868 cout << "Reading gear ratios..." << flush;
869 kGear.X(env.GetValue("Zd_GearRatio[U_mot/U_tel]", 1000.0));
870 kGear.Y(env.GetValue("Az_GearRatio[U_mot/U_tel]", 1000.0));
871
872 kResRE.Y(0);
873 if (fMac1 && !fMac1->IsZombieNode())
874 kResRE.Y(fMac1->GetRes());
875 else
876 if (fMac3 && !fMac3->IsZombieNode())
877 kResRE.Y(fMac3->GetRes());
878 else
879 kResRE.Y(env.GetValue("Az_ResRE[re/U_mot]", 1500));
880
881 kResRE.X(0);
882 if (fMac2 && !fMac2->IsZombieNode())
883 kResRE.X(fMac2->GetRes());
884 else
885 kResRE.X(env.GetValue("Zd_ResRE[re/U_mot]", 1500));
886
887 kResSE.X(0);
888 if (fZd1 && !fZd1->IsZombieNode())
889 kResSE.X(fZd1->GetPhysRes());
890 else
891 if (fZd2 && !fZd2->IsZombieNode())
892 kResSE.X(fZd2->GetPhysRes());
893 else
894 kResSE.X(env.GetValue("Zd_ResSE[se/U_mot]", 16384));
895
896 kResSE.Y(0);
897 if (fAz && !fAz->IsZombieNode())
898 kResSE.Y(fAz->GetPhysRes());
899 else
900 kResSE.Y(env.GetValue("Az_ResSE[se/U_mot]", 16384));
901
902 // believing the Macs manual '*4' shouldn't be necessary, but it is.
903 // Because the a RE is 4 quad counts.
904 // Calculating speeds we have to convert back to qc
905 kResRE *= 4;
906 kGearTot = kResRE*kGear;
907
908 cout << "done." << endl;
909
910 cout << " * Setting Gear Ratios:" << endl;
911 cout << " --------------------" << endl;
912 cout << " * X: " << kGear.X() << "*" << kResRE.X()/4 << "/" << kResSE.X() << "=4*" << kGearTot.X() << "/" << kResSE.X() << endl;
913 cout << " * Y: " << kGear.Y() << "*" << kResRE.Y()/4 << "/" << kResSE.Y() << "=4*" << kGearTot.Y() << "/" << kResSE.Y() << endl;
914}
915/*
916void MCosy::InitSync()
917{
918 if (!fMac3)
919 {
920 lout << "Unable to Init Sync! Mac3 not available." << endl;
921 return;
922 }
923
924 const int res = fMac3->GetVelRes();
925
926 fMac3->SetVelocity(0.3*res);
927 fMac3->SetAcceleration(0.2*res);
928 fMac3->SetDeceleration(0.2*res);
929 fMac3->StartPosSync();
930}
931*/
932void MCosy::TalkThreadSeTest()
933{
934// if (fZd1->IsZombieNode() || fZd2->IsZombieNode())
935 // return;
936
937 if (fHist)
938 {
939 lout << "You are much too fast... try again." << endl;
940 return;
941 }
942
943 fHist = new TH2F("Diff", "Difference of SE values",
944 201, fMin.Zd(), fMax.Zd(), 41, -10.5, 10.5);
945 fHist->SetXTitle("ZA [\\circ]");
946 fHist->SetYTitle("\\Delta SE");
947
948 Double_t offset = 0;
949
950 int cnt = 0;
951
952 lout << "Starting Shaftencoder Test..." << endl;
953
954 while (fBackground==kBgdSeTest)
955 {
956 fZd1->ResetPosHasChanged();
957 fZd2->ResetPosHasChanged();
958
959 while (!fZd1->PosHasChanged() && !fZd2->PosHasChanged() &&
960 fBackground==kBgdSeTest)
961 usleep(1);
962
963 const Double_t pos[3] = {
964 (fZd1->GetPos()+8192)%16384,
965 (fZd2->GetPos()+8192)%16384,
966 fAz->GetPos() };
967
968 //
969 // Estimate Offset from the first ten positions
970 //
971 if (cnt++<10)
972 {
973 offset += pos[0]+pos[1];
974 continue;
975 }
976 if (cnt==11)
977 {
978 offset /= 10;
979 cnt++;
980 }
981
982 Double_t apos = (pos[0]-pos[1])/2 * TMath::TwoPi() / kResSE.X();
983
984 ZdAz bend = fBending.CorrectBack(ZdAz(apos, pos[2]))*kRad2Deg;
985 fHist->Fill(bend.Zd(), pos[0]+pos[1]-offset);
986 }
987
988 lout << "Shaftencoder Test Stopped... displaying Histogram." << endl;
989
990 fBackground=kBgdSeTestDispl;
991}
992
993void MCosy::TalkThreadGear()
994{
995// if (fZd1->IsZombieNode() || fZd2->IsZombieNode())
996 // return;
997
998 if (fHist)
999 {
1000 lout << "You are much too fast... try again." << endl;
1001 return;
1002 }
1003
1004 fHist = new TH3F("Gear", "Gear Ratio Re/Se",
1005 (int)((fMax.Zd()-fMin.Zd())/2.5+1), fMin.Zd(), fMax.Zd(),
1006 (int)((fMax.Az()-fMin.Az())/2.5+1), fMin.Az(), fMax.Az(),
1007 61, 349.5, 500.5);
1008
1009 fHist->SetXTitle("Zd [\\circ]");
1010 fHist->SetYTitle("Az [\\circ]");
1011 fHist->SetZTitle("Re/Se");
1012
1013 lout << "Starting Gear determination..." << endl;
1014
1015 ZdAz se0 = GetSePos();
1016 ZdAz re0 = GetRePosPdo();
1017
1018 while (fBackground==kBgdGear)
1019 {
1020 fZd1->ResetPosHasChanged();
1021 fZd2->ResetPosHasChanged();
1022 fAz->ResetPosHasChanged();
1023
1024 while (!fZd1->PosHasChanged() && !fZd2->PosHasChanged() &&
1025 !fAz->PosHasChanged() && fBackground==kBgdGear)
1026 usleep(1);
1027
1028 ZdAz se = GetSePos();
1029 ZdAz re = GetRePosPdo();
1030
1031 ZdAz dse = se-se0;
1032 ZdAz dre = re-re0;
1033
1034 if (fabs(dse.Zd())*144>kResSE.X()) // Each 2.5deg (144)
1035 {
1036 se0.Zd(se.Zd());
1037 re0.Zd(re.Zd());
1038
1039 se -= dse/2;
1040
1041 ZdAz bend = fBending.CorrectBack(se*TMath::TwoPi()/kResSE)*kRad2Deg;
1042 ((TH3*)fHist)->Fill(bend.Zd(), bend.Az(), dre.Zd()/dse.Zd());
1043 }
1044
1045 if (fabs(dse.Az())*144>kResSE.Y()) // Each 2.5deg (144)
1046 {
1047 se0.Az(se.Az());
1048 re0.Az(re.Az());
1049
1050 se -= dse/2;
1051
1052 ZdAz bend = fBending.CorrectBack(se*TMath::TwoPi()/kResSE)*kRad2Deg;
1053 ((TH3*)fHist)->Fill(bend.Az(), bend.Az(), dre.Az()/dse.Az());
1054 }
1055 }
1056 lout << "Gear Test Stopped... displaying Histogram." << endl;
1057
1058 fBackground=kBgdGearDispl;
1059}
1060
1061void MCosy::TalkThread()
1062{
1063 /* ========== FIXME? =============
1064 if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
1065 return;
1066 */
1067
1068 if (fMac1 && fMac2)
1069 {
1070 fMac1->ReqPos();
1071 fMac2->ReqPos();
1072 }
1073
1074 //InitSync();
1075
1076 /*** FOR DEMO MODE ***/
1077 if (!fZd1 || !fZd2 || !fAz)
1078 return;
1079 /*** FOR DEMO MODE ***/
1080
1081 //
1082 // Start the Network
1083 //
1084 while (1)
1085 {
1086 //
1087 // wait until a tracking session is started
1088 //
1089 while (fBackground==kBgdNone)
1090 usleep(1);
1091
1092 switch (fBackground)
1093 {
1094 case kBgdNone:
1095 continue;
1096/*#ifndef NEWALGO
1097 case kBgdTracking:
1098 TalkThreadTracking();
1099 continue;
1100#endif*/
1101 case kBgdSeTest:
1102 TalkThreadSeTest();
1103 continue;
1104
1105 case kBgdGear:
1106 TalkThreadGear();
1107 continue;
1108
1109 default:
1110 continue;
1111 }
1112 }
1113}
1114
1115ZdAz MCosy::GetPointingPos() const
1116{
1117 if (fZd1->IsZombieNode() || fZd2->IsZombieNode() || fAz->IsZombieNode())
1118 return ZdAz(0, 0);
1119
1120 // GetPointingPos [deg]
1121 const ZdAz seist = GetSePos()*TMath::TwoPi()/kResSE; // [rad]
1122 return fBending.CorrectBack(seist)*TMath::RadToDeg();
1123}
1124
1125Bool_t MCosy::HandleTimer(TTimer *t)
1126{
1127 const Int_t rc = fMutexGui.TryLock();
1128 if (rc==13)
1129 cout << "MCosy::HandleTimer - mutex is already locked by this thread" << endl;
1130
1131 if (rc)
1132 {
1133 lout << "* GUI update skipped due to locked mutex." << endl;
1134 return kTRUE;
1135 }
1136
1137 //
1138 // Update Gui, foremer MTGui.
1139 //
1140 if (fZd1)
1141 fZd1->DisplayVal();
1142 if (fZd2)
1143 fZd2->DisplayVal();
1144 if (fAz)
1145 fAz->DisplayVal();
1146
1147 Byte_t avail = 0;
1148
1149 avail |= (fMac1 && !fMac1->IsZombieNode()) ? 0x01 : 0;
1150 avail |= (fMac2 && !fMac2->IsZombieNode()) ? 0x02 : 0;
1151 avail |= (fMac3 && !fMac3->IsZombieNode()) ? 0x04 : 0;
1152 avail |= (fZd1 && !fZd1->IsZombieNode()) ? 0x08 : 0;
1153 avail |= (fZd2 && !fZd2->IsZombieNode()) ? 0x10 : 0;
1154 avail |= (fAz && !fAz->IsZombieNode()) ? 0x20 : 0;
1155
1156 if (HasError())
1157 SetStatus(MDriveCom::kError);
1158
1159
1160 ZdAz bendist = fStatus&MDriveCom::kTracking ? fTrackingPos : GetPointingPos();
1161
1162 //cout << (fStatus&MDriveCom::kTracking?"TRA: ":"POS: ") << bendist.Zd() << " " << bendist.Az() << endl;
1163
1164 fCom->SendReport(fStatus, fRaDec, fZdAzSoll, bendist, fTrackingError);
1165
1166 fWin->UpdateWeather(*fCom);
1167 fWin->Update(bendist, fTrackingError, fVelocity, /*fOffset,*/
1168 fRaDec, fZdAzSoll, fStatus, avail);
1169
1170 lout.UpdateGui();
1171
1172 const Bool_t trigger = fTriggerDisplay;
1173 fTriggerDisplay = kFALSE;
1174
1175 if (fBackground==kBgdSeTestDispl || (trigger&&fBackground==kBgdSeTest))
1176 DisplayHistTestSe(!trigger);
1177
1178 if (fBackground==kBgdGearDispl || (trigger&&fBackground==kBgdGear))
1179 DisplayHistGear(!trigger);
1180
1181 if (fMutexGui.UnLock()==13)
1182 cout << "MCosy::HandleTimer - tried to unlock mutex locked by other thread." << endl;
1183
1184 return kTRUE;
1185}
1186
1187void MCosy::DisplayHistTestSe(Bool_t del)
1188{
1189 lout << "Displaying histogram..." << endl;
1190
1191 TH2F &hist = *(TH2F*)fHist;
1192
1193 if (del)
1194 {
1195 fHist = NULL;
1196 fBackground = kBgdNone;
1197 }
1198
1199 TCanvas *c=new TCanvas("c1", "", 1000, 1000);
1200 c->Divide(1,2);
1201
1202 c->cd(1);
1203 TH2 *h=(TH2*)hist.DrawCopy();
1204
1205 TProfile *p = h->ProfileX("_pfx", -1, 9999, "s");
1206 p->SetLineColor(kBlue);
1207 p->Draw("same");
1208 p->SetBit(kCanDelete);
1209
1210 c->cd(2);
1211
1212 TH1F p2("spread", "Spread of the differences", hist.GetNbinsX(), hist.GetBinLowEdge(1),
1213 hist.GetBinLowEdge(hist.GetNbinsX()+1));
1214 p2.SetXTitle("Zd [\\circ]");
1215 for (int i=0; i<hist.GetNbinsX(); i++)
1216 p2.SetBinError(i, p->GetBinError(i));
1217 p2.SetLineColor(kRed);
1218 p2.SetStats(0);
1219 p2.DrawCopy();
1220
1221 if (del)
1222 delete &hist;
1223}
1224
1225void MCosy::DisplayHistGear(Bool_t del)
1226{
1227 lout << "Displaying histogram..." << endl;
1228
1229 TH3F &hist = *(TH3F*)fHist;
1230
1231 if (del)
1232 {
1233 fHist = NULL;
1234 fBackground = kBgdNone;
1235 }
1236
1237 TCanvas *c=new TCanvas("c1", "", 1000, 1000);
1238 c->Divide(2,2);
1239
1240 // ----------
1241
1242 c->cd(1);
1243 TH2D &h1=*(TH2D*)hist.Project3D("zx"); // Zd
1244 h1.SetTitle(" Gear Ratio Zenith Distance [re/se] ");
1245 h1.SetXTitle("Zd [\\circ]");
1246 h1.Draw();
1247 h1.SetBit(kCanDelete);
1248
1249 TProfile *p1 = h1.ProfileX("_pfx", -1, 9999, "s");
1250 p1->SetLineColor(kBlue);
1251 p1->Draw("same");
1252 p1->SetBit(kCanDelete);
1253
1254 // ----------
1255
1256 c->cd(2);
1257 TH2D &h2=*(TH2D*)hist.Project3D("zy"); // Az
1258 h2.SetTitle(" Gear Ratio Azimuth [re/se] ");
1259 h2.SetXTitle("Zd [\\circ]");
1260 h2.Draw();
1261 h2.SetBit(kCanDelete);
1262
1263 TProfile *p2 = h2.ProfileX("_pfx", -1, 9999, "s");
1264 p2->SetLineColor(kBlue);
1265 p2->Draw("same");
1266 p2->SetBit(kCanDelete);
1267
1268 // ----------
1269
1270 c->cd(3);
1271
1272 TAxis &axe1 = *h1.GetXaxis();
1273
1274 TH1F f1("spreadzd", " Spread Zenith Distance ",
1275 axe1.GetNbins(), axe1.GetXmin(), axe1.GetXmax());
1276 f1.SetXTitle("Zd [\\circ]");
1277 for (int i=0; i<axe1.GetNbins(); i++)
1278 f1.SetBinError(i, p1->GetBinError(i));
1279 f1.SetLineColor(kRed);
1280 f1.SetStats(0);
1281 f1.DrawCopy();
1282
1283 c->cd(4);
1284
1285 // ----------
1286
1287 TAxis &axe2 = *h2.GetXaxis();
1288
1289 TH1F f2("spreadaz", " Spread Azimuth ",
1290 axe2.GetNbins(), axe2.GetXmin(), axe2.GetXmax());
1291 f2.SetXTitle("Az [\\circ]");
1292 for (int i=0; i<axe2.GetNbins(); i++)
1293 f2.SetBinError(i, p2->GetBinError(i));
1294 f2.SetLineColor(kRed);
1295 f2.SetStats(0);
1296 f2.DrawCopy();
1297
1298 // ----------
1299
1300 if (del)
1301 delete &hist;
1302}
1303
1304// --------------------------------------------------------------------------
1305//
1306// Start the work of the application:
1307//
1308// Start the Can-Network.
1309// Start the MCosy::TalkThread thread.
1310// turn on the gui update
1311//
1312void MCosy::Start()
1313{
1314 // Don't call this function twice!
1315 Network::Start();
1316
1317 CheckForError();
1318
1319 ReadConfig();
1320
1321 lout << "- Starting TX Thread." << endl;
1322 fTTalk = new MTTalk(this);
1323
1324 lout << "- Starting GUI update." << endl;
1325 fUpdateGui->TurnOn();
1326}
1327
1328// --------------------------------------------------------------------------
1329//
1330// Start the work of the application:
1331//
1332// Turn of the gui update
1333// stop the MCosy::TalkThread thread.
1334// Stop the network
1335//
1336void MCosy::Stop()
1337{
1338 lout << "- Stopping GUI update." << endl;
1339 fUpdateGui->TurnOff();
1340 lout << "- GUI Update stopped." << endl;
1341
1342 delete fTTalk;
1343 lout << "- TX Thread stopped." << endl;
1344
1345 Network::Stop();
1346}
1347
1348// --------------------------------------------------------------------------
1349//
1350// Disable the synchronization by using a negative CAN Id for id2.
1351//
1352void MCosy::Constructor(Int_t id1, Int_t id2, Int_t id3,
1353 Int_t id4, Int_t id5, Int_t id6)
1354{
1355 //
1356 // Create Nodes
1357 //
1358 lout << "- Setting up network." << endl;
1359
1360 fMac1=new Macs(id1, "Mac/Az", lout);
1361 fMac2=new Macs(id3, "Mac/Zd", lout);
1362 if (id2>=0)
1363 fMac3=new Macs(id2, "Mac/Az-Sync", lout);
1364
1365 fZd1=new ShaftEncoder(id4, "SE/Zd1", lout);
1366 fZd2=new ShaftEncoder(id5, "SE/Zd2", lout);
1367 fAz =new ShaftEncoder(id6, "SE/Az", lout);
1368
1369 fZd1->SetReport(fOutRep);
1370 fZd2->SetReport(fOutRep);
1371 fAz->SetReport(fOutRep);
1372
1373 fAz->SetMotor(fMac1);
1374 fZd1->SetMotor(fMac2);
1375 fZd2->SetMotor(fMac2);
1376
1377 lout << "- Connecting devices to network." << endl;
1378
1379 //
1380 // Connect the devices to the network
1381 //
1382 SetNode(fMac1);
1383 SetNode(fMac2);
1384 if (id2>=0)
1385 SetNode(fMac3);
1386 SetNode(fZd1);
1387 SetNode(fZd2);
1388 SetNode(fAz);
1389
1390 //
1391 // Create Gui Event timer and Gui
1392 //
1393 lout << "- Initializing GUI Timer." << endl;
1394 fUpdateGui = new TTimer(this, 100); // 100ms
1395
1396 lout << "- Starting GUI." << endl;
1397 fWin=new MGCosy(fObservatory, this, gClient->GetRoot(), 1, 1);
1398}
1399/*
1400void MCosy::ConstructorSE(Int_t id4, Int_t id5, Int_t id6)
1401{
1402 //
1403 // Create Nodes
1404 //
1405 lout << "- Setting up network." << endl;
1406
1407 fZd1=new ShaftEncoder(id4, "SE/Zd1", lout);
1408 fZd2=new ShaftEncoder(id5, "SE/Zd2", lout);
1409 fAz =new ShaftEncoder(id6, "SE/Az", lout);
1410
1411 lout << "- Connecting devices to network." << endl;
1412
1413 //
1414 // Connect the devices to the network
1415 //
1416 SetNode(fZd1);
1417 SetNode(fZd2);
1418 SetNode(fAz);
1419
1420 //
1421 // Create Gui Event timer and Gui
1422 //
1423 lout << "- Initializing GUI Timer." << endl;
1424 fUpdateGui = new TTimer(this, 100); // 100ms
1425
1426 lout << "- Starting GUI." << endl;
1427 fWin=new MGCosy(fObservatory, this, gClient->GetRoot(), 1, 1);
1428}
1429
1430void MCosy::ConstructorDemo()
1431{
1432 //
1433 // Create Nodes
1434 //
1435 lout << "- Setting up network." << endl;
1436
1437 //
1438 // Create Gui Event timer and Gui
1439 //
1440 lout << "- Initializing GUI Timer." << endl;
1441 fUpdateGui = new TTimer(this, 100); // 100ms
1442
1443 lout << "- Starting GUI." << endl;
1444 fWin=new MGCosy(fObservatory, this, gClient->GetRoot(), 1, 1);
1445}
1446*/
1447
1448TString MCosy::GetFileName(const char *fmt)
1449{
1450 // FIXME: Timeout missing
1451 while (1)
1452 {
1453 MTime time(-1);
1454 const TString name = Form(fmt, (const char*)time.GetFileName());
1455 if (gSystem->AccessPathName(name, kFileExists))
1456 return name;
1457 break;
1458
1459 usleep(1000);
1460 }
1461 return "";
1462}
1463
1464MCosy::MCosy(/*int mode,*/ const char *dev, const int baud, MLog &out)
1465: Network(dev, baud, out), fObservatory(MObservatory::kMagic1), fStarguider(NULL), fZd1(0), fZd2(0), fAz(0), fMac1(0), fMac2(0), fMac3(0), fBackground(kBgdNone), fStatus(MDriveCom::kStopped), fOutTp(0), fOutRep(0)
1466{
1467 TEnv env(".cosyrc");
1468 const Int_t id1 = env.GetValue("Az_Id-MAC1", 1); //1
1469 const Int_t id2 = env.GetValue("Az_Id-MAC2", 2); //2
1470 const Int_t id3 = env.GetValue("Zd_Id-MAC", 3); //3
1471 const Int_t id4 = env.GetValue("Zd_Id-SE1", 4); //4
1472 const Int_t id5 = env.GetValue("Zd_Id-SE2", 5); //5
1473 const Int_t id6 = env.GetValue("Az_Id-SE", 6); //6
1474
1475 TString name = GetFileName("rep/cosy_%s.rep");
1476 cout << "Open Repfile: " << name << endl;
1477 fOutRep = new MLog(name, kTRUE);
1478 *fOutRep << "[Drive Report File]" << endl;
1479 *fOutRep << "Version <cvs>" << endl;
1480 *fOutRep << "Date " << MTime(-1) << endl;
1481 *fOutRep << "[Reports]" << endl;
1482
1483/*
1484 lout << "- Program in ";
1485 switch (mode)
1486 {
1487 case 0:
1488 lout << "<<Standard mode>>" << endl;*/
1489 fBending.Load("bending.txt");
1490 Constructor(id1, id2, id3, id4, id5, id6);/*
1491 break;
1492 case 1:
1493 lout << "<<SE mode>>" << endl;
1494 fBending.Load("bending.txt");
1495 ConstructorSE(id4, id5, id6);
1496 break;
1497 default:
1498 lout << "<<Demo mode>>" << endl;
1499 ConstructorDemo();
1500 }
1501*/
1502 lout.SetOutputGui(fWin->GetLog(), kTRUE);
1503
1504 fZd1->SetDisplay(fWin->GetLabel2());
1505 fZd2->SetDisplay(fWin->GetLabel3());
1506 fAz->SetDisplay(fWin->GetLabel1());
1507
1508 fCom = new MDriveCom(this, *fOutRep);
1509 fCom->Start();
1510}
1511
1512void MCosy::TerminateApp()
1513{
1514 cout << "MCosy::TerminateApp()" << endl;
1515/*
1516 Int_t rc;
1517 TGMessageBox msg(this, gClient->GetRoot(),
1518 "Information",
1519 "Cosy is shutting down the system - this may take wa while!",
1520 kMBIconExclamation,
1521 kMBOK, //kMBClose
1522 &rc, 0);
1523*/
1524
1525 lout.DisableOutputDevice(MLog::eGui);
1526 // FIXME: WHY DOES THIS CRASH THE APPLICATIOn WHILE TRAKING?
1527 // lout.SetOutputGui(NULL, kFALSE);
1528
1529 gApplication->Terminate(0);
1530}
1531
1532MCosy::~MCosy()
1533{
1534 if (fOutTp)
1535 {
1536 *fOutTp << "END" << endl;
1537 delete fOutTp;
1538 }
1539 delete fOutRep;
1540
1541 cout << "Deleting GUI timer." << endl;
1542
1543 delete fUpdateGui;
1544 delete fCom;
1545
1546 cout << "Deleting Nodes." << endl;
1547
1548 fZd1->SetReport(0);
1549 fZd2->SetReport(0);
1550 fAz->SetReport(0);
1551
1552 delete fAz;
1553 delete fZd1;
1554 delete fZd2;
1555 delete fMac1;
1556 delete fMac2;
1557 if (fMac3)
1558 delete fMac3;
1559
1560 cout << "Deleting MGCosy." << endl;
1561
1562 lout.DisableOutputDevice(MLog::eGui);
1563
1564 delete fWin;
1565
1566 cout << "MGCosy destructed." << endl;
1567}
Note: See TracBrowser for help on using the repository browser.