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

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