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

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