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

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