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

Last change on this file since 9435 was 9435, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 27.3 KB
Line 
1#include "MCosy.h"
2#include "MCosy.h"
3
4#include <iomanip>
5#include <fstream>
6
7#include <TEnv.h>
8#include <TTimer.h>
9#include <TApplication.h>
10
11//#include "MLog.h"
12#include "MLogManip.h"
13
14#include "MEnv.h"
15#include "MTime.h"
16#include "MPointing.h"
17
18#include "MGCosy.h"
19#include "MDriveCom.h"
20#include "MStarguider.h"
21#include "SlaStars.h"
22#include "MTracking.h"
23
24#include "dkc.h"
25
26ClassImp(MCosy);
27
28using namespace std;
29
30typedef struct tm tm_t;
31
32//#define EXPERT
33#undef EXPERT
34
35/*
36ZdAz MCosy::CorrectTarget(const ZdAz &src, const ZdAz &dst)
37{
38 // CorrectTarget [se]
39
40 // src [se]
41 // dst [rad]
42
43 // fAltMax = 70
44 // fAltMin = -105/110
45 // fAzMin = -355
46 // fAzMax = 355
47
48 ZdAz source = src * 360.0/16384.0;
49 ZdAz dest = dst * TMath::RadToDeg();
50
51 if (dest.Zd()>-3 && dest.Zd()<3)
52 dest.Zd(dest.Zd()<0?-3:3);
53
54 if (dest.Zd()>-1e-6 && dest.Zd()<1e-6)
55 return dst*(16384.0/k2Pi);
56
57 const float fZdMin = -67;
58 const float fZdMax = 67;
59 const float fAzMin = -29;
60 const float fAzMax = 423;
61
62 //
63 // This corrects to target for the shortest distance, not for the fastest move!
64 //
65 ZdAz s = source-dest;
66
67 float min = s.Sqr();
68
69 //
70 // Is it enought to search inside one revolution?
71 //
72 ZdAz ret = dest;
73
74 for (int i=-5; i<5+1; i++)
75 {
76 const ZdAz p(i%2 ? -dest.Zd() : dest.Zd(), dest.Az() - i*180);
77
78 //
79 // Range Check
80 //
81 if (p.Zd()<fZdMin || p.Zd()>fZdMax)
82 continue;
83
84 if (p.Az()<fAzMin || p.Az()>fAzMax)
85 continue;
86
87 //
88 // Calculate distance
89 //
90 s = source-p;
91
92 const float dist = s.Sqr();
93
94 if (dist > min)
95 continue;
96
97 //
98 // New shortest distance
99 //
100 ret = p;
101 min = dist;
102 }
103 return ret*(16384.0/360.0);
104}
105*/
106// --------------------------------------------------------------------------
107//
108// GetSePos, reads the Shaftencoder positions from the Can-drivers
109// for the shaftencoders. The two shaft encoders at the elevation axis
110// are avaraged. The values are returned as a ZdAz object.
111//
112// If one of the two shaftencoders on the elevation axis is missing
113// the other one's position is returned.
114//
115// The positions are alway up-to-date because the shaftencoders are
116// sending all changes immediatly.
117//
118ZdAz MCosy::GetSePos() const
119{
120 const Double_t pa = fMac1 ? (Double_t)fMac1->GetPdoPos2()/fMac1->GetPosRes() : 0;
121 const Double_t p1 = fMac2 ? (Double_t)fMac2->GetPdoPos2()/fMac2->GetPosRes() : 0;
122
123 return ZdAz(p1, pa);
124}
125
126// --------------------------------------------------------------------------
127//
128// check for a break-signal (from the msgqueue) and errors.
129//
130int MCosy::StopWaitingForSDO() const
131{
132 return 0/*Break() || HasError()*/;
133}
134
135// --------------------------------------------------------------------------
136//
137// Waits for a movement to become finished.
138//
139// First waits for all peding Sdos, then waits until both motors are stopped
140// or waiting for SDOs was stopped (either by an error or by Break)
141//
142void MCosy::WaitForEndMovement()
143{
144 // FIXME, what when waiting times out (Zombie)
145 if (!fMac1 || !fMac2)
146 return;
147
148 while ((fMac1->IsPositioning() || fMac2->IsPositioning()) &&
149 !(Break() || HasError() || HasZombie()))
150 usleep(1);
151
152 if (!Break() && !HasError() && !HasZombie())
153 return;
154
155 MTime t(-1);
156 gLog << inf << t << " - MCosy::WaitForEndMovement aborted...";
157 if (Break())
158 gLog << " Break signal...";
159 if (HasError())
160 gLog << " Network has error...";
161 if (HasZombie())
162 gLog << " Network has zombie...";
163 gLog << endl;
164}
165
166// --------------------------------------------------------------------------
167//
168// Check for an error...
169//
170// This is ment for usage after the Action: All Motors Stop.
171//
172void MCosy::CheckForError()
173{
174 //
175 // Check all Can-Nodes for an Error. If there is no error the motor
176 // status is set to stopped.
177 //
178 if (HasError() || HasZombie())
179 {
180 SetStatus(MDriveCom::kError);
181 return;
182 }
183
184 if (fMac1->IsPositioning() || fMac2->IsPositioning())
185 SetStatus(MDriveCom::kMoving);
186 else
187 SetStatus(MDriveCom::kStopped);
188
189 //
190 // If there is an error, the error status is set to Error.
191 //
192
193 /*
194 FIXME: HANDLINGE ERROR
195
196 //
197 // Now try to handle the error.
198 //
199 fMac1->HandleError();
200 fMac2->HandleError();
201
202 //
203 // If the error couldn't get solved return
204 //
205 if (HasError())
206 return;
207
208 //
209 // Set motor status to stopped
210 //
211 SetStatus(MDriveCom::kStopped);
212 */
213}
214
215Bool_t MCosy::CheckRange(const ZdAz &d) const
216{
217 // d [rad]
218
219 if (d.Zd()<fMin.Zd())
220 {
221 gLog << err << "ERROR: Requested Zenith Angle below negative endswitch." << endl;
222 return kFALSE;
223 }
224
225 if (d.Zd()>fMax.Zd())
226 {
227 gLog << err << "ERROR: Requested Zenith Angle behind positive endswitch." << endl;
228 return kFALSE;
229 }
230
231 if (d.Az()<fMin.Az())
232 {
233 gLog << err << "ERROR: Requested Azimuth Angle below negative endswitch." << endl;
234 return kFALSE;
235 }
236
237 if (d.Az()>fMax.Az())
238 {
239 gLog << err << "ERROR: Requested Azimuth Angle behind positive endswitch." << endl;
240 return kFALSE;
241 }
242
243
244 return kTRUE;
245}
246
247ZdAz MCosy::AlignTrackingPos(ZdAz pointing) const
248{
249 // pointing [rad]
250 // AlignTrackingPos [deg]
251
252 pointing *= TMath::RadToDeg();
253
254 if (pointing.Zd()<0)
255 {
256 pointing.Zd(-pointing.Zd());
257 pointing.Az(pointing.Az()+180);
258 //gLog << "ZD=-ZD Az+=180" << endl;
259 }
260
261 const ZdAz se = GetSePos()*TMath::TwoPi(); // [rad]
262 const ZdAz unbendedse = fBending.CorrectBack(se)*TMath::RadToDeg(); // ist pointing
263
264 //gLog << "Unbended: " << unbendedse.Zd() << " " << unbendedse.Az() << endl;
265
266 do
267 {
268 const Double_t d = unbendedse.Az() - pointing.Az();
269 if (d>-180 && d<=180)
270 break;
271
272 //gLog << "AZ += " << TMath::Sign(360., d) << endl;
273
274 pointing.Az(pointing.Az()+TMath::Sign(360., d));
275 } while (1);
276
277 return pointing/TMath::RadToDeg();
278/*
279 const Bool_t rc = CheckRange(pointing);
280 za = pointing/TMath::RadToDeg(); // [rad]
281
282 if (!rc)
283 gLog << "Error: Aligned position out of Range." << endl;
284
285 return rc;*/
286}
287
288/*
289Double_t MCosy::Starguider(Double_t mjd, ZdAz &dest) const
290{
291 ifstream fin("pointingpos.txt");
292 if (!fin)
293 return -1;
294
295 Double_t mjd0, zd, az;
296 fin >> mjd0 >> zd >> az;
297
298 mjd0 += 52000;
299
300 if (mjd0+1./24/60 <mjd)
301 return -1;
302
303 ZdAz point=AlignTrackingPos(ZdAz(zd, az)/TMath::RadToDeg());
304
305 const ZdAz diff = (dest-point)*TMath::RadToDeg();
306
307 if (diff.Zd()>5 || diff.Az()>5)
308 {
309 cout << "Starguider deviation too large... dZd=" << diff.Zd() <<" dAz="<<diff.Az() << endl;
310 return -1;
311 }
312
313 dest -= point;
314 dest *= -kGearTot/TMath::TwoPi(); // [re]
315
316 cout << "Using Starguider... dZd=" << dest.Zd() << " dAz=" << dest.Az() << endl;
317
318 return (mjd-mjd0) * (24*60*60); // [s]
319}
320*/
321
322// --------------------------------------------------------------------------
323//
324// Move the telescope to the given position. The position must be given in
325// a ZdAz object in rad.
326//
327// The first positioning is done absolutely. If we didn't reach the
328// correct psotion we try to correct for this by 10 relative position
329// maneuvers. If this doesn't help positioning failed.
330//
331// As a reference the shaftencoder values are used.
332//
333int MCosy::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
334{
335 MSlewing point(this);
336
337 // Default: point.SetPointAcc(0.03, 0.01);
338 point.SetPointAcc(0.03, 0.01);
339 point.SetPointVelocity(0.3);
340
341 return point.SetPosition(dst, track);
342}
343
344void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
345{
346 MTracking track(this);
347 track.SetOut(fOutRep);
348
349 track.SetPointAcc(0.03, 0.01);
350 track.SetPointVelocity(0.3);
351 track.SetTrackAcc(0.01, 0.01);
352
353 track.TrackPosition(dst);
354}
355
356void MCosy::TrackPositionGRB(const RaDec &dst) // ra, dec [rad]
357{
358 TrackPosition(dst);
359 return;
360
361 MTracking track(this);
362 track.SetOut(fOutRep);
363 track.SetPointAcc(0.09, 0.03);
364 track.SetPointVelocity(1.0);
365 track.SetTrackAcc(0.01, 0.01);
366
367 track.TrackPosition(dst);
368}
369
370// --------------------------------------------------------------------------
371//
372// Stops the movement of both motors.
373//
374// Sets the status to stopping. Sets the deceleration to 50% of the maximum.
375// stops. Quits the revolution mode and wait for the end of the movement.
376//
377void MCosy::StopMovement()
378{
379 //
380 // Set status to Stopping
381 //
382 SetStatus(MDriveCom::kStopping);
383
384 //
385 // set deceleration to 50%
386 //
387 gLog << inf2 << "Stopping movement..." << endl;
388 if (fMac1 && fMac2)
389 {
390 // FIXME: Makes sense?
391 fMac1->SetAcceleration(TMath::Nint(0.03*1000000000));
392 fMac2->SetAcceleration(TMath::Nint(0.09*1000000000));
393
394 fMac1->SetRpmMode(FALSE);
395 fMac2->SetRpmMode(FALSE);
396 }
397
398 //
399 // Wait for the movement to really be finished.
400 //
401#ifdef EXPERT
402 cout << "Waiting for end of movement..." << endl;
403#endif
404 WaitForEndMovement();
405
406 //
407 // Check whether everything works fine.
408 //
409 CheckForError();
410#ifdef EXPERT
411 cout << "Movement stopped." << endl;
412#endif
413}
414
415bool MCosy::CheckNetwork()
416{
417 if (!HasConnection())
418 {
419 gLog << warn << "- No connection to network." << endl;
420 return false;
421 }
422
423 CheckForError();
424
425 if (HasZombie())
426 {
427 gLog << warn << "- Found Zombies in Network..." << endl;
428 if (!RebootZombies())
429 return false;
430 }
431
432 /*
433 FIXME HANDLING ERROR
434 */
435 if (HasError())
436 {
437 fMac1->HandleError();
438 fMac2->HandleError();
439 if (HasError() || HasZombie())
440 return false;
441 }
442
443 CheckForError();
444
445 return fMac1->IsOperative() && fMac2->IsOperative();
446}
447
448Int_t MCosy::Proc(int msg, void *mp)
449{
450 switch (msg)
451 {
452 case WM_WAIT:
453 gLog << inf2 << "Wait for execution of Proc(WM_*, ): done." << endl;
454 return 0;
455
456 case WM_STOP:
457 //cout << "MCosy::Proc: Stop." << endl;
458 if (!CheckNetwork())
459 return 0xebb0;
460 StopMovement();
461 return 0;
462
463 case WM_TPOINT:
464 {
465 //cout << "WM_TPoint: start." << endl;
466 SlaStars sla(fObservatory);
467 sla.Now();
468
469 RaDec rd = *((RaDec*)mp);
470 cout << "TPoint Star: " << rd.Ra()/15 << "h " << rd.Dec() << "°" << endl;
471
472 AltAz za=sla.CalcAltAz(rd*TMath::DegToRad())*TMath::RadToDeg();
473
474 if (!fOutTp)
475 {
476 //
477 // open tpoint file
478 //
479 const TString name = GetFileName("tpoint", "old-tpoint", "txt");
480 cout << "TPoint-Cosy File ********* " << name << " ********** " << endl;
481
482 fOutTp = new ofstream(name);
483 *fOutTp << "Magic Model TPOINT data file" << endl;
484 *fOutTp << ": ALTAZ" << endl;
485 *fOutTp << "49 48 0 ";
486 *fOutTp << sla.GetTime().Year() << " " << sla.GetTime().Month() << " " << sla.GetTime().Day() << " ";
487 *fOutTp << /*"20 1013.25 300 0.5 0.55 0.0065" <<*/ endl;
488 // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
489 }
490
491 cout << " Alt/Az: " << za.Alt() << "° " << za.Az() << "°" << endl;
492 *fOutTp << setprecision(7) << za.Az() << " " << za.Alt() << " ";
493
494 ZdAz sepos = GetSePos()*TMath::TwoPi();
495 za.Set(TMath::Pi()/2-sepos.Zd(), sepos.Az());
496 za *= TMath::RadToDeg();
497
498 cout << " SE-Pos: " << za.Alt() << "° " << za.Az() << "°" << endl;
499 *fOutTp << fmod(za.Az()+360, 360) << " " << za.Alt() << " ";
500
501 if (fStarguider)
502 {
503 XY tp = fStarguider->GetCoordinates();
504 *fOutTp << 90-tp.X() << " " << tp.Y() << " ";
505 }
506
507 *fOutTp << rd.Ra()/15 << " " << rd.Dec() << " " << setprecision(11) << sla.GetMjd() << endl;
508
509 //cout << "WM_TPoint: done. (return 0xaffe)" << endl;
510 }
511 return 0xca1b;
512
513 case WM_STARGTPOINT:
514 if (fStarguider)
515 fStarguider->StartTPoint();
516 return 0xca1c;
517
518 case WM_STARGMODE:
519 if (fStarguider)
520 fStarguider->StartStarguider();
521 return 0xca1c;
522
523 case WM_TRACKPOS:
524 //cout << "WM_TrackPosition: start." << endl;
525 {
526 if (!CheckNetwork())
527 return 0xebb0;
528
529 ZdAz dest = *((ZdAz*)mp) * TMath::DegToRad();
530 //if (!SetPosition(dest, kTRUE))
531 // return 0x1234;
532
533 SlaStars sla(fObservatory);
534 sla.Now();
535
536 RaDec rd = sla.CalcRaDec(dest);
537 TrackPosition(rd);
538 }
539 //cout << "WM_TrackPosition: done. (return 0xabcd)" << endl;
540 return 0xabcd;
541
542 case WM_ARM:
543 //cout << "WM_Position: start." << endl;
544 {
545 if (!CheckNetwork())
546 return 0xebb0;
547
548 const bool arm = mp ? *((bool*)mp) : true;
549 if (arm)
550 {
551 fMac1->Arm();
552 fMac2->Arm();
553 }
554 else
555 {
556 fMac1->Disarm();
557 fMac2->Disarm();
558 }
559 }
560 //cout << "WM_Position: done. (return 0x7777)" << endl;
561 return 0x9999;
562
563 case WM_POSITION:
564 //cout << "WM_Position: start." << endl;
565 {
566 if (!CheckNetwork())
567 return 0xebb0;
568
569 ZdAz dest = *((ZdAz*)mp);
570 SetPosition(dest*TMath::DegToRad());
571 }
572 //cout << "WM_Position: done. (return 0x7777)" << endl;
573 return 0x7777;
574
575 case WM_POSITION1:
576 //cout << "WM_Position1: start." << endl;
577 {
578 if (!CheckNetwork())
579 return 0xebb0;
580
581 ZdAz dest = *((ZdAz*)mp);
582 SetPosition(dest*TMath::DegToRad(), kTRUE);
583 }
584 //cout << "WM_Position: done. (return 0x7777)" << endl;
585 return 0x7777;
586
587 case WM_PREPS:
588 //cout << "WM_Track: START" << endl;
589 {
590 if (!CheckNetwork())
591 return 0xebb0;
592
593 const char *preps = (const char*)mp;
594 cout << "Preposition command to " << preps << " received." << endl;
595
596 ifstream fin("prepos.txt");
597 if (!fin)
598 {
599 cout << "ERROR: cannot open prepos.txt." << endl;
600 return 0xebb1;
601 }
602
603 while (1)
604 {
605 Double_t zd, az;
606 fin >> zd >> az;
607
608 TString str;
609 str.ReadLine(fin);
610 if (!fin)
611 break;
612
613 str.ToLower();
614
615 if (str.Strip(TString::kBoth)==preps)
616 {
617 ZdAz dest(zd, az);
618 SetPosition(dest*TMath::DegToRad());
619 return 0x7979;
620 }
621 cout << "ERROR - Requested preposition not found in file..." << endl;
622 }
623 }
624 //cout << "WM_Track: done. (return 0x8888)" << endl;
625 return 0x7878;
626/*
627 case WM_TESTSE:
628 //cout << "WM_TestSe: start." << endl;
629 fBackground = mp ? kBgdSeTest : kBgdNone;
630 //cout << "WM_TestSe: done. (return 0x1e51)" << endl;
631 return 0x1e51;
632
633 case WM_GEAR:
634 //cout << "WM_Gear: start." << endl;
635 fBackground = mp ? kBgdGear : kBgdNone;
636 //cout << "WM_Gear: done. (return 0xfeaf)" << endl;
637 return 0xfeaf;
638
639 case WM_DISPLAY:
640 //cout << "WM_Display: start." << endl;
641 fTriggerDisplay = kTRUE;
642 //cout << "WM_Disply: done. (return 0xd1e1)" << endl;
643 return 0xd1e1;
644 */
645 case WM_TRACK:
646 case WM_GRB:
647 //cout << "WM_Track/GRB: START" << endl;
648 {
649 RaDec dest = ((RaDec*)mp)[0];
650 if (fStarguider)
651 fStarguider->SetPointingPosition(((RaDec*)mp)[1]);
652 if (!CheckNetwork())
653 return 0xebb0;
654
655 if (msg==WM_TRACK)
656 TrackPosition(dest*TMath::DegToRad());
657 else
658 TrackPositionGRB(dest*TMath::DegToRad());
659 }
660 //cout << "WM_Track/GRB: done. (return 0x8888)" << endl;
661 return 0x8888;
662
663 case WM_NEWTRACK:
664 //cout << "WM_NewTrack: START" << endl;
665 fRaDec = *((RaDec*)mp);
666 //cout << "WM_NewTrack: done. (return 0x9999)" << endl;
667 return 0x9999;
668
669 case WM_LOADBENDING:
670 //cout << "WM_LoadBending: START" << endl;
671 fBending.Load("bending.txt");
672 //cout << "WM_LoadBending: done. (return 0xbe0d)" << endl;
673 return 0xbe0d;
674
675 case WM_RESETBENDING:
676 //cout << "WM_ResetBending: START" << endl;
677 fBending.Reset();
678 //cout << "WM_ResetBending: done. (return 0xbe0e)" << endl;
679 return 0xbe0e;
680
681 case WM_CALCALTAZ:
682 {
683 cout << endl;
684
685 SlaStars sla(fObservatory);
686 sla.Now();
687
688 XY xy = *((XY*)mp);
689 RaDec rd(xy.X()*15., xy.Y()); // [deg]
690
691 ZdAz a1 = sla.CalcZdAz(rd*TMath::DegToRad()); // [rad]
692
693 cout << "Ra/Dec source: " << xy.X() << "h " << xy.Y() << "°" << endl;
694 cout << "Zd/Az target: " << a1.Zd()*TMath::RadToDeg() << "° " << a1.Az()*TMath::RadToDeg() << "°" << endl;
695
696 if (fMac1 && fMac2)
697 a1 = AlignTrackingPos(a1);
698
699 a1 = fBending(a1);
700 CheckRange(a1);
701 a1 *= TMath::RadToDeg();
702
703 const ZdAz a2 = a1/360;
704
705 cout << "Zd/Az bended: " << a1.Zd() << "° " << a1.Az() << "°" << endl;
706 cout << "SE bended: " << a2.Zd() << " " << a2.Az() << endl;
707 }
708 return 0xa17a;
709
710 case WM_ENDSWITCH:
711 {
712 ZdAz pos = GetSePos()*TMath::TwoPi();
713 pos = fBending.SubtractOffsets(pos)*TMath::RadToDeg();
714
715 cout << "Endswitch Position: Zd=" << pos.Zd() << "° Az=";
716 cout << pos.Az() << "°" << endl;
717 }
718
719 return 0x1010;
720
721 case WM_QUIT:
722 cout << "WM_Quit: now." << endl;
723 if (!CheckNetwork())
724 {
725 gLog << err << "ERROR: Cannot shutdown network." << endl;
726 gLog << " Please shutdown the drive system manually" << endl;
727 }
728 TerminateApp();
729 cout << "WM_Quit: done." << endl;
730 return 0xaaaa;
731 }
732 cout << "MCosy::Proc: Unknown message 0x" << msg << endl;
733 return 0xffffffff;
734}
735
736void MCosy::ReadConfig(MEnv &env)
737{
738 gLog << inf2 << "Reading telescope range..." << flush;
739 const Double_t amin = env.GetValue("Az_Min[deg]", -95.0);
740 const Double_t zmin = env.GetValue("Zd_Min[deg]", -75.0);
741 fMin.Set(zmin, amin);
742
743 const Double_t amax = env.GetValue("Az_Max[deg]", 305.0);
744 const Double_t zmax = env.GetValue("Zd_Max[deg]", 98.25);
745 fMax.Set(zmax, amax);
746 gLog << "done." << endl;
747
748 gLog << all << flush;
749
750 gLog << " * Min: " << zmin << "deg " << amin << "deg" << endl;
751 gLog << " * Max: " << zmax << "deg " << amax << "deg" << endl;
752
753 fMin = fBending.AddOffsets(fMin*TMath::DegToRad());
754 fMax = fBending.AddOffsets(fMax*TMath::DegToRad());
755
756 gLog << " * Min': " << fMin.Zd()*TMath::RadToDeg() << "deg " << fMin.Az()*TMath::RadToDeg() << "deg" << endl;
757 gLog << " * Max': " << fMax.Zd()*TMath::RadToDeg() << "deg " << fMax.Az()*TMath::RadToDeg() << "deg" << endl;
758}
759
760ZdAz MCosy::GetPointingPos() const
761{
762 if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
763 return ZdAz(0, 0);
764
765 // GetPointingPos [deg]
766 const ZdAz seist = GetSePos()*TMath::TwoPi(); // [rad]
767 return fBending.CorrectBack(seist)*TMath::RadToDeg();
768}
769
770Bool_t MCosy::HandleTimer(TTimer *t)
771{
772 const Int_t rc = fMutexGui.TryLock();
773 if (rc==13)
774 gLog << warn << "MCosy::HandleTimer - mutex is already locked by this thread" << endl;
775
776 if (rc)
777 {
778 gLog << warn << "* GUI update skipped due to locked mutex." << endl;
779 return kTRUE;
780 }
781
782 //
783 // Update Gui, foremer MTGui.
784 //
785 if (fMac1)
786 fMac1->DisplayVal();
787 if (fMac2)
788 fMac2->DisplayVal();
789
790 /*
791 Byte_t avail = 0;
792
793 avail |= (fMac1 && !fMac1->IsZombieNode()) ? 0x01 : 0;
794 avail |= (fMac2 && !fMac2->IsZombieNode()) ? 0x02 : 0;
795// avail |= (!(fStatus&MDriveCom::kError) && 1 ? 0x40 : 0;
796 */
797 Bool_t armed = kTRUE;
798
799 armed &= fMac1 && fMac1->IsArmed();
800 armed &= fMac2 && fMac2->IsArmed();
801
802 if (HasError())
803 SetStatus(MDriveCom::kError);
804
805 const TString stataz = fMac1 ? fMac1->GetStatusDKC() : "";
806 const TString statzd = fMac2 ? fMac2->GetStatusDKC() : "";
807
808 const UInt_t stat1 = fMac1 ? fMac1->GetStatusPdo3() : 0;
809 const UInt_t stat2 = fMac2 ? fMac2->GetStatusPdo3() : 0;
810
811 ZdAz bendist = GetPointingPos();
812
813 //cout << (fStatus&MDriveCom::kTracking?"TRA: ":"POS: ") << bendist.Zd() << " " << bendist.Az() << endl;
814
815 static MTimeout tout(0);
816 if (tout.HasTimedOut())
817 {
818 tout.Start(999);
819 fCom->SendReport(fStatus, fRaDec, fZdAzSoll, bendist, fTrackingError, armed);
820 }
821
822 fWin->UpdateWeather(*fCom);
823 fWin->Update(bendist, fTrackingError, /*fVelocity, fOffset,*/
824 fRaDec, fZdAzSoll, fStatus, (stat1<<8)|stat2, HasConnection(), armed, statzd, stataz);
825
826 gLog.UpdateGui();
827
828 if (fMutexGui.UnLock()==13)
829 gLog << warn << "MCosy::HandleTimer - tried to unlock mutex locked by other thread." << endl;
830
831 return kTRUE;
832}
833
834// --------------------------------------------------------------------------
835//
836// Start the work of the application:
837//
838// Start the Can-Network.
839// Start the MCosy::TalkThread thread.
840// turn on the gui update
841//
842void MCosy::Start(MEnv &env)
843{
844 // Don't call this function twice!
845 Network::Start();
846
847 CheckForError();
848
849 ReadConfig(env);
850
851 gLog << inf << "- Starting GUI update." << endl;
852 fUpdateGui->TurnOn();
853}
854
855// --------------------------------------------------------------------------
856//
857// Start the work of the application:
858//
859// Turn of the gui update
860// stop the MCosy::TalkThread thread.
861// Stop the network
862//
863void MCosy::Stop()
864{
865 gLog << inf << "- Stopping GUI update." << endl;
866 fUpdateGui->TurnOff();
867 gLog << inf << "- GUI Update stopped." << endl;
868
869 gLog << inf << "- Stopping CAN network." << endl;
870 Network::Stop();
871 gLog << inf << "- CAN network stopped." << endl;
872
873 gLog << inf << "- Stopping message queue." << endl;
874 CancelThread();
875 gLog << inf << "- Message queue stopped." << endl;
876}
877
878// --------------------------------------------------------------------------
879//
880// Disable the synchronization by using a negative CAN Id for id2.
881//
882void MCosy::Constructor(Int_t id1, Int_t id2)
883{
884 //
885 // Create Nodes
886 //
887 gLog << inf << "- Setting up network." << endl;
888
889 fMac1=new Dkc(id1, "DKC/Az");
890 fMac2=new Dkc(id2, "DKC/Zd");
891
892 fMac1->SetReport(fOutRep);
893 fMac2->SetReport(fOutRep);
894
895 gLog << inf << "- Connecting devices to network." << endl;
896
897 //
898 // Connect the devices to the network
899 //
900 SetNode(fMac1);
901 SetNode(fMac2);
902
903 //
904 // Create Gui Event timer and Gui
905 //
906 gLog << inf << "- Initializing GUI Timer." << endl;
907 fUpdateGui = new TTimer(this, 100); // 100ms
908
909 gLog << all << "- Starting GUI." << endl;
910 fWin=new MGCosy(fObservatory, this);
911}
912
913/*
914void MCosy::ConstructorDemo()
915{
916 //
917 // Create Nodes
918 //
919 gLog << "- Setting up network." << endl;
920
921 //
922 // Create Gui Event timer and Gui
923 //
924 gLog << "- Initializing GUI Timer." << endl;
925 fUpdateGui = new TTimer(this, 100); // 100ms
926
927 gLog << "- Starting GUI." << endl;
928 fWin=new MGCosy(fObservatory, this, gClient->GetRoot(), 1, 1);
929}
930*/
931
932TString MCosy::GetFileName(const char *path, const char *name, const char *ext)
933{
934 // FIXME: Timeout missing
935
936 while (1)
937 {
938 MTime time(-1);
939
940 // This is the full qualified date which is part of the name
941 const TString clock = time.GetStringFmt("%Y%m%d_%H%M%S");
942
943 // This gives the night in which the date belongs to
944 time.SetMjd(TMath::Nint(time.GetMjd()));
945
946 const TString night = time.GetStringFmt("%Y_%m_%d");
947
948 const TString dir = Form("%s/%s", path, night.Data());
949 const TString fname = Form("%s_%s.%s", name, clock.Data(), ext);
950
951 const TString full = Form("%s/%s", dir.Data(), fname.Data());
952
953 gSystem->mkdir(dir, kTRUE);
954
955 if (gSystem->AccessPathName(full, kFileExists))
956 return full;
957
958 break;// !!!!!!!!!!!!!!!!!!!!!!!
959
960 usleep(1000);
961 }
962 return "";
963}
964
965MCosy::MCosy(MEnv &env, MDriveCom *com, const char *pointing)
966: Network(), fObservatory(MObservatory::kMagic1), fStarguider(NULL),
967fMac1(0), fMac2(0), fStatus(MDriveCom::kStopped), fOutTp(0), fOutRep(0)
968{
969 const Int_t id1 = env.GetValue("Az_Id", 1);
970 const Int_t id2 = env.GetValue("Zd_Id", 3);
971
972 TString name = GetFileName("rep", "cosy", "rep");
973 gLog << inf << "Open Repfile: " << name << endl;
974 fOutRep = new MLog(name, kTRUE);
975 *fOutRep << all << "[Drive Report File]" << endl;
976 *fOutRep << "Version <cvs>" << endl;
977 *fOutRep << "Date " << MTime(-1) << endl;
978 *fOutRep << "[Reports]" << endl;
979
980/*
981 gLog << "- Program in ";
982 switch (mode)
983 {
984 case 0:
985 gLog << "<<Standard mode>>" << endl;*/
986 gLog << all << "Reading pointing model from " << pointing << "..." << endl;
987 if (fBending.Load(pointing))
988 gLog << all << "Reading pointing model from " << pointing << " successfull." << endl;
989 else
990 gLog << err << "ERROR - Reading pointing model from " << pointing << endl;
991 Constructor(id1, id2);/*
992 break;
993 case 1:
994 gLog << "<<SE mode>>" << endl;
995 fBending.Load("bending.txt");
996 ConstructorSE(id4, id5, id6);
997 break;
998 default:
999 gLog << "<<Demo mode>>" << endl;
1000 ConstructorDemo();
1001 }
1002*/
1003
1004 gLog.SetOutputGui(fWin->GetLog(), kTRUE);
1005
1006 fMac2->SetDisplay(fWin->GetLabel2());
1007 fMac1->SetDisplay(fWin->GetLabel1());
1008
1009 fCom = com;//new MDriveCom(this, addr, tx, rx, fOutRep);
1010 fCom->SetOutRep(fOutRep);
1011 // fCom->Start();
1012}
1013
1014void MCosy::TerminateApp()
1015{
1016 gLog << inf2 << "MCosy::TerminateApp()" << endl;
1017/*
1018 Int_t rc;
1019 TGMessageBox msg(this, gClient->GetRoot(),
1020 "Information",
1021 "Cosy is shutting down the system - this may take wa while!",
1022 kMBIconExclamation,
1023 kMBOK, //kMBClose
1024 &rc, 0);
1025*/
1026
1027 gLog.DisableOutputDevice(MLog::eGui);
1028 // FIXME: WHY DOES THIS CRASH THE APPLICATIOn WHILE TRAKING?
1029 // gLog.SetOutputGui(NULL, kFALSE);
1030
1031 gApplication->Terminate(0);
1032}
1033
1034MCosy::~MCosy()
1035{
1036 if(fCom)
1037 {
1038 fCom->SetMsgQueue(NULL);
1039 fCom->SetOutRep(NULL);
1040 }
1041
1042 gLog << inf2 << "Deleting GUI timer." << endl;
1043 // FIXME: Wait until last Update was finished!!!
1044 delete fUpdateGui;
1045
1046 //fMutexGui.Lock();
1047
1048 // Now the files can safely be closed
1049 gLog << inf2 << "Closing output files." << endl;
1050 if (fOutTp)
1051 {
1052 *fOutTp << "END" << endl;
1053 delete fOutTp;
1054 }
1055
1056 delete fOutRep;
1057
1058 //gLog << inf2 << "Deleting CC communication." << endl;
1059 //delete fCom;
1060
1061 gLog << inf2 << "Deleting Nodes." << endl;
1062 fMac1->SetReport(0);
1063 fMac2->SetReport(0);
1064
1065 delete fMac1;
1066 delete fMac2;
1067
1068 gLog << inf2 << "Deleting MGCosy." << endl;
1069
1070 gLog.DisableOutputDevice(MLog::eGui);
1071
1072 delete fWin;
1073
1074 gLog << inf2 << "MGCosy destructed." << endl;
1075}
Note: See TracBrowser for help on using the repository browser.