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

Last change on this file since 1699 was 1699, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 40.5 KB
Line 
1#include "MCosy.h"
2
3#include <iomanip.h>
4#include <fstream.h>
5#include <iostream.h>
6
7#include <TROOT.h>
8#include <TEnv.h>
9#include <TSystem.h>
10#include <TApplication.h>
11#include <TTimer.h>
12
13#include "MGCosy.h"
14#include "SlaStars.h"
15
16#include "slalib/slalib.h" // FIXME: REMOVE
17
18#include "macs.h"
19#include "base/timer.h"
20#include "shaftencoder.h"
21
22//#include <sys/resource.h> // PRIO_PROCESS
23
24ClassImp(MCosy);
25
26typedef struct tm tm_t;
27
28/*
29#define GEAR_RATIO_ALT 2475.6 // [U_mot/U_tel(360deg)]
30#define GEAR_RATIO_AZ 5891.7 // [U_mot/U_tel(360deg)]
31
32#define RES_RE 500 // [re/U_mot]
33#define RES_SE 16384 // [se/U_tel(360deg)]
34*/
35/*
36 #define GEAR_RATIO_ALT (75.55*16384/1500) // 75.25 VERY IMPORTANT! unit=U_mot/U_tel
37 #define GEAR_RATIO_AZ (179.8*16384/1500) // VERY IMPORTANT! unit=U_mot/U_tel
38*/
39
40//const XY kGearRatio (GEAR_RATIO_ALT*RES_RE/RES_SE, GEAR_RATIO_AZ*RES_RE/RES_SE); //[re/se]
41//const XY kGearRatio2(GEAR_RATIO_ALT*RES_RE/360.0, GEAR_RATIO_AZ*RES_RE/360.0); //[re/deg]
42
43double MCosy::Rad2SE(double rad) const
44{
45 return 16384.0/k2Pi*rad;
46}
47
48double MCosy::Rad2ZdRE(double rad) const
49{
50 return 16384.0/k2Pi*rad*kGearRatio.X();
51}
52
53double MCosy::Rad2AzRE(double rad) const
54{
55 return 16384.0/k2Pi*rad*kGearRatio.Y();
56}
57
58double MCosy::Deg2ZdRE(double rad) const
59{
60 return rad*kGearRatio2.X();
61}
62
63double MCosy::Deg2AzRE(double rad) const
64{
65 return rad*kGearRatio2.Y();
66}
67
68ZdAz MCosy::CorrectTarget(const ZdAz &src, const ZdAz &dst)
69{
70 // CorrectTarget [se]
71
72 // src [se]
73 // dst [rad]
74
75 // fAltMax = 70
76 // fAltMin = -105/110
77 // fAzMin = -355
78 // fAzMax = 355
79
80 ZdAz source = src * 360.0/16384.0;
81 ZdAz dest = dst * kRad2Deg;
82
83 if (dest.Zd()>-3 && dest.Zd()<3)
84 dest.Zd(dest.Zd()<0?-3:3);
85
86 if (dest.Zd()>-1e-6 && dest.Zd()<1e-6)
87 return dst*(16384.0/k2Pi);
88
89 const float fZdMin = -67;
90 const float fZdMax = 67;
91 const float fAzMin = -29;
92 const float fAzMax = 423;
93
94 //
95 // This corrects to target for the shortest distance, not for the fastest move!
96 //
97 ZdAz s = source-dest;
98
99 float min = s.Sqr();
100
101 //
102 // Is it enought to search inside one revolution?
103 //
104 ZdAz ret = dest;
105
106 for (int i=-5; i<5+1; i++)
107 {
108 const ZdAz p(i%2 ? -dest.Zd() : dest.Zd(), dest.Az() - i*180);
109
110 //
111 // Range Check
112 //
113 if (p.Zd()<fZdMin || p.Zd()>fZdMax)
114 continue;
115
116 if (p.Az()<fAzMin || p.Az()>fAzMax)
117 continue;
118
119 //
120 // Calculate distance
121 //
122 s = source-p;
123
124 const float dist = s.Sqr();
125
126 if (dist > min)
127 continue;
128
129 //
130 // New shortest distance
131 //
132 ret = p;
133 min = dist;
134 }
135 return ret*(16384.0/360.0);
136}
137
138// --------------------------------------------------------------------------
139//
140// GetSePos, reads the Shaftencoder positions from the Can-drivers
141// for the shaftencoders. The two shaft encoders at the elevation axis
142// are avaraged. The values are returned as a ZdAz object.
143//
144// The positions are alway up-to-date because the shaftencoders are
145// sending all changes immediatly.
146//
147ZdAz MCosy::GetSePos()
148{
149 //
150 // Get the values
151 //
152 const int p0 = fZd1 ? fZd1->GetPos() : 0;
153 const int p1 = fZd2 ? fZd2->GetPos() : 0;
154 const int p2 = fAz ? fAz->GetPos() : 0;
155
156 const int a0 = p0; //p0>8192?p0-16384:p0;
157 const int a1 = p1; //p1>8192?p1-16384:p1;
158 const int a2 = p2; //p2>8192?p2-16384:p2;
159
160 //
161 // interpolate shaft encoder positions
162 //
163 const float a = (float)(a0-a1)/2;
164
165 //
166 // calculate 'regelabweichung'
167 //
168 return ZdAz(a, a2);
169}
170
171// --------------------------------------------------------------------------
172//
173// request the current positions from the rotary encoders.
174// use GetRePos to get the psotions. If the request fails the function
175// returns kFALSE, otherwise kTRUE
176//
177Bool_t MCosy::RequestRePos()
178{
179 if (!(fMac1 && fMac2))
180 return kTRUE;
181
182 //
183 // Send request
184 //
185 fMac2->RequestSDO(0x6004);
186 fMac1->RequestSDO(0x6004);
187
188 //
189 // Wait until the objects are received.
190 //
191 WaitForSdos();
192
193 //
194 // If waitng was not interrupted everything is ok. return.
195 //
196 if (!StopWaitingForSDO())
197 return kTRUE;
198
199 //
200 // If the waiting was interrupted due to a network error,
201 // print some logging message.
202 //
203 if (HasError())
204 lout << "Error while requesting re pos from Macs (SDO #6004)" << endl;
205
206 return kFALSE;
207}
208
209// --------------------------------------------------------------------------
210//
211// reads the Rotary encoder positions from the last request of the Macs.
212//
213// The positions are returned as a ZdAz object. Use RequestRePos to request
214// the current positions first.
215//
216ZdAz MCosy::GetRePos()
217{
218 return fMac1 && fMac2 ? ZdAz(fMac2->GetPos(), fMac1->GetPos()) : ZdAz(0,0);
219}
220
221// --------------------------------------------------------------------------
222//
223// reads the Rotary encoder positions from the Macs.
224//
225// The positions are returned as a ZdAz object. The positions are the ones
226// which are send as PDOs to the computer. This is done at a given
227// frequency. Which means, that this positions are not ought to be
228// up-to-date.
229//
230ZdAz MCosy::GetRePosPdo()
231{
232 return ZdAz(fMac2->GetPdoPos(), fMac1->GetPdoPos());
233}
234
235// --------------------------------------------------------------------------
236//
237// set the velocity and accelerations for position maneuvers.
238//
239// The acceleratin is set as given (in percent of maximum).
240// The velocity is given in percent, depending on the ratio (<1 or >1)
241// one of the axis becomes a slower velocity. This is used for maneuvers
242// in which both axis are moved synchromously and should reach their
243// target position at the same time.
244//
245void MCosy::SetPosVelocity(const Float_t ratio, Float_t vel, Float_t acc)
246{
247 //
248 // Set velocities
249 //
250 const int vr = fMac1->GetVelRes();
251
252 vel *= vr;
253 acc *= vr;
254
255 if (ratio <1)
256 {
257 fMac1->SetVelocity(vel);
258 fMac1->SetAcceleration(acc);
259 fMac1->SetDeceleration(acc);
260
261 fMac2->SetVelocity(vel*ratio);
262 fMac2->SetAcceleration(acc*ratio);
263 fMac2->SetDeceleration(acc*ratio);
264 }
265 else
266 {
267 fMac1->SetVelocity(vel/ratio);
268 fMac1->SetAcceleration(acc/ratio);
269 fMac1->SetDeceleration(acc/ratio);
270
271 fMac2->SetVelocity(vel);
272 fMac2->SetAcceleration(acc);
273 fMac2->SetDeceleration(acc);
274 }
275}
276
277// --------------------------------------------------------------------------
278//
279// Does a relative positioning.
280//
281// The steps to move are given in a ZdAz object relative to the current
282// position. The coordinates are given in Roteryencoder steps.
283// Axis 1 is moved only if axe1==kTRUE, Axis 2 is moved only
284// if Axis 2==kTRUE. The function waits for the movement to be finished.
285//
286void MCosy::DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2)
287{
288 SetStatus(MCosy::kMoving);
289
290 if (axe1) fMac2->StartRelPos(rd.Zd());
291 if (axe2) fMac1->StartRelPos(rd.Az());
292
293 cout << "Waiting for positioning..." << flush;
294
295 WaitForEndMovement();
296
297 cout << "done." << endl;
298}
299
300// --------------------------------------------------------------------------
301//
302// check for a break-signal (from the msgqueue) and errors.
303//
304int MCosy::StopWaitingForSDO() const
305{
306 return Break() || HasError();
307}
308
309// --------------------------------------------------------------------------
310//
311// Waits for a movement to become finished.
312//
313// First waits for all peding Sdos, then waits until both motors are stopped
314// or waiting for SDOs was stopped (either by an error or by Break)
315//
316void MCosy::WaitForEndMovement()
317{
318 WaitForSdos();
319
320 while ((fMac1->IsPositioning() || fMac2->IsPositioning()) && !StopWaitingForSDO())
321 usleep(1);
322}
323
324// --------------------------------------------------------------------------
325//
326// Check for an error...
327//
328// This is ment for usage after the Action: All Motors Stop.
329//
330void MCosy::CheckForError()
331{
332 //
333 // Check all Can-Nodes for an Error. If there is no error the motor
334 // status is set to stopped.
335 //
336 if (!HasError())
337 {
338 SetStatus(MCosy::kStopped);
339 return;
340 }
341
342 //
343 // If there is an error, the error status is set to Error.
344 //
345 SetStatus(MCosy::kError);
346
347 //
348 // No try to handle the error.
349 //
350 fMac1->HandleError();
351 fMac2->HandleError();
352
353 //
354 // If the error couldn't get solved return
355 //
356 if (HasError())
357 return;
358
359 //
360 // Set motor status to stopped
361 //
362 SetStatus(MCosy::kStopped);
363}
364
365// --------------------------------------------------------------------------
366//
367// Move the telescope to the given position. The position must be given in
368// a ZdAz object in rad.
369//
370// The first positioning is done absolutely. If we didn't reach the
371// correct psotion we try to correct for this by 10 relative position
372// maneuvers. If this doesn't help positioning failed.
373//
374// As a reference the shaftencoder values are used.
375//
376int MCosy::SetPosition(const ZdAz &dst) // [rad]
377{
378 // FIXME: Correct by fOffset ?
379
380 if (!(fMac1 && fMac2))
381 {
382 cout << "SetPosition: No MACS!" << endl;
383 return TRUE;
384 }
385
386 //
387 // Calculate new target position (shortest distance to go)
388 //
389 const ZdAz src = GetSePos();//*TMath::Pi()*2/16384;;
390
391 //
392 // Because we agreed on I don't search for the shortest move
393 // anymore
394 //
395 // const ZdAz dest = CorrectTarget(src, dst);
396 //
397 const ZdAz bend = fBending(dst);
398 const ZdAz dest = bend*16384/2/TMath::Pi();
399
400 lout << "Positioning to Target..." << endl;
401 cout << "Source Zd: " << src.Zd() << "se Az:" << src.Az() << "se" << endl;
402 cout << "Destination Zd: " << Rad2SE(dst.Zd()) << "se Az:" << Rad2SE(dst.Az()) << "se" << endl;
403 cout << "Bend'd Dest Zd: " << Rad2SE(bend.Zd()) << "se Az:" << Rad2SE(bend.Az()) << "se" << endl;
404 cout << "Shortest Dest Zd: " << dest.Zd() << "se Az:" << dest.Az() << "se" << endl;
405
406 for (int i=0; i<10 && !StopWaitingForSDO(); i++)
407 {
408 //
409 // Get Shaft Encoder Positions
410 //
411 const ZdAz p=GetSePos();
412
413 //
414 // calculate control deviation and rounded cd
415 //
416 ZdAz rd = dest-p; // [se]
417
418 ZdAz cd = rd; // [se]
419 cd.Round();
420
421 //
422 // Check if there is a control deviation on the axis
423 //
424 const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
425 const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
426
427 //
428 // check if we reached the correct position already
429 //
430 if (!cdzd && !cdaz)
431 {
432 lout << "Positioning done in " << i << (i==1?" step.":" steps.") << endl;
433 SetStatus(MCosy::kStopped);
434 return TRUE;
435 }
436
437 //
438 // change units from se to re
439 //
440 rd *= kGearRatio; // [re]
441
442 //
443 // Initialize Velocities so that we reach both positions
444 // at the same time
445 //
446 if (i)
447 SetPosVelocity(1.0, 0.1, 0.1);
448 else
449 SetPosVelocity(fabs(rd.Ratio()), 0.9, 0.5);
450
451 rd.Round();
452
453 /*
454 cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
455 cout << " + APOS: Zd=" << setw(6) << p.Zd() << "se Az=" << setw(6) << p.Az() << "se" << endl;
456 cout << " + dZd=" << setw(6) << cd.Zd() << "se dAz=" << setw(6) << cd.Az() << "se" << endl;
457 cout << " + dZd=" << setw(6) << rd.Zd() << "re dAz=" << setw(6) << rd.Az() << "re" << endl;
458 cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X() << "se Az=" << setw(6) << kGearRatio.Y() << "se" << endl;
459 */
460
461 //
462 // repositioning (relative)
463 //
464 DoRelPos(rd, cdzd, cdaz);
465 }
466
467 StopMovement();
468 lout << "Warning: Requested position not reached." << endl;
469 return FALSE;
470}
471
472// --------------------------------------------------------------------------
473//
474// Sets the tracking velocity
475//
476// The velocities are given in a ZdAz object in re/min. Return kTRUE
477// in case of success, kFALSE in case of failure.
478//
479Bool_t MCosy::SetVelocity(ZdAz v)
480{
481 //
482 // Send the new velocities for both axes.
483 //
484 fMac2->SendSDO(0x3006, 1, (LWORD_t)v.Zd()); // SetRpmVelocity [re/min]
485 fMac1->SendSDO(0x3006, 1, (LWORD_t)v.Az()); // SetRpmVelocity [re/min]
486
487 //
488 // Wait for the objects to be OKed.
489 //
490 WaitForSdos();
491
492 //
493 // If the waiting for the objects wasn't interrupted return kTRUE
494 //
495 if (!StopWaitingForSDO())
496 return kTRUE;
497
498 //
499 // print a message if the interruption was due to a Can-node Error
500 //
501 if (HasError())
502 lout << "Error while setting velocity (SDO #3006)" << endl;
503
504 return kFALSE;
505}
506
507// --------------------------------------------------------------------------
508//
509// Initializes Tracking mode
510//
511// Initializes the accelerations of both axes with 90% of the maximum
512// acceleration. Set the status for moving and tracking and starts thr
513// revolution mode.
514//
515void MCosy::InitTracking()
516{
517 if (!(fMac1 && fMac2))
518 return;
519
520 //
521 // Start revolution mode
522 //
523 fMac2->SetAcceleration(0.90*fMac2->GetVelRes());
524 fMac2->SetDeceleration(0.90*fMac2->GetVelRes());
525
526 fMac1->SetAcceleration(0.90*fMac1->GetVelRes());
527 fMac1->SetDeceleration(0.90*fMac1->GetVelRes());
528
529 SetStatus(MCosy::kMoving | MCosy::kTracking);
530
531 fMac2->SetRpmMode(TRUE);
532 fMac1->SetRpmMode(TRUE);
533}
534
535// --------------------------------------------------------------------------
536//
537// Limits the speed.
538//
539// This function should work as a limiter. If a tracking error is too large
540// to be corrected fast enough we would get enormous velocities. These
541// velocities are limited to the maximum velocity.
542//
543void MCosy::LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const
544{
545 //
546 // How to limit the speed. If the wind comes and blowes
547 // we cannot forbid changing of the sign. But on the other hand
548 // we don't want fast changes!
549 //
550
551 ULong_t vrzd = fMac1->GetVelRes();
552 ULong_t vraz = fMac2->GetVelRes();
553
554#define sgn(x) (x<0?-1:1)
555
556 const Float_t limit = 0.25;
557/*
558 if (sgn(vt->Az()) != sgn(vcalc.Az()))
559 vt->Az(0);
560// else
561 {
562 if (fabs(vt->Az()) < fabs(vcalc.Az()) *0.5)
563 vt->Az(0.5*vcalc.Az());
564
565 if (fabs(vt->Az()) > fabs(vcalc.Az()) *1.5)
566 vt->Az(1.5*vcalc.Az());
567 }
568
569 if (sgn(vt->Zd()) != sgn(vcalc.Zd()))
570 vt->Zd(0);
571// else
572 {
573 if (fabs(vt->Zd()) > fabs(vcalc.Az()) *1.5)
574 vt->Zd(1.5*vcalc.Zd());
575
576 if (fabs(vt->Zd()) < fabs(vcalc.Az()) *0.5)
577 vt->Zd(0.5*vcalc.Zd());
578 }
579 */
580
581 if (sgn(vt->Az()) != sgn(vcalc.Az())
582 && fabs(vt->Az()) < limit*fabs(vcalc.Az())
583 )
584 vt->Az(0);
585 else
586 if (fabs(vt->Az()) > 0.9*vraz)
587 {
588 lout << "Warning: Azimuth speed limit exceeded. Limiting speed to 90% max." << endl;
589 vt->Az(0.9*vraz*sgn(vt->Az()));
590 }
591
592 if (sgn(vt->Zd()) != sgn(vcalc.Zd())
593 && fabs(vt->Zd()) < limit*fabs(vcalc.Zd())
594 )
595 vt->Zd(0);
596 else
597 if (fabs(vt->Zd()) > 0.9*vrzd)
598 {
599 lout << "Warning: Altitude speed limit exceeded. Limiting speed to 90% max." << endl;
600 vt->Zd(0.9*vrzd*sgn(vt->Zd()));
601 }
602}
603
604void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
605{
606 SlaStars sla;
607
608 //
609 // Position to actual position
610 //
611 sla.SetMjd2Now();
612 ZdAz dest = sla.CalcZdAz(dst);
613
614 if (!SetPosition(dest))
615 {
616 lout << "Error: Cannot start tracking, positioning failed." << endl;
617 return;
618 }
619
620 //
621 // calculate offset from present se position
622 //
623 const ZdAz sepos = GetSePos()*kGearRatio;
624
625 if (!RequestRePos())
626 return;
627
628 //
629 // Estimate Offset before starting to track
630 //
631 fOffset = sepos-GetRePos();
632
633 /*
634 cout << "Sepos: " << sepos.Zd() << "re, " << sepos.Az() << "re" << endl;
635 cout << "Repos: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
636 cout << "Offset: " << fOffset.Zd() << "re, " << fOffset.Az() << "re" << endl;
637 */
638
639 //
640 // Init accelerations and Rpm Mode
641 //
642 InitTracking();
643
644 XY xy(Rad2Deg(dst.Ra())*24/360, Rad2Deg(dst.Dec()));
645
646 lout << "Start tracking:";
647 lout << " Ra: " << xy.X() << "h " << "Dec: " << xy.Y() << "\xb0" << endl;
648
649 ofstream fout("coordinates.txt");
650 fout << xy;
651 fout.close();
652
653 //
654 // Initialize Tracker (slalib or starguider)
655 //
656 fRaDec = dst;
657
658 if (!(fMac1 && fMac2))
659 return;
660
661 fTracking = kTRUE;
662
663//--- ofstream fout("log/cosy.pos");
664//--- fout << "Tracking:";
665//--- fout << " Ra: " << Rad2Deg(dst.Ra()) << "\x9c ";
666//--- fout << "Dec: " << Rad2Deg(dst.Dec()) << "\x9c" << endl << endl;
667//--- fout << " Mjd/10ms V/re/min/4" << endl;
668
669 //
670 // We want to reach the theoretical position exactly in about 0.5s
671 //
672 const float dt = 1; // 1 second
673 while (!StopWaitingForSDO())
674 {
675 //
676 // The loop should not be executed faster than the ramp of
677 // a change in the velocity can be followed.
678 // (This is important on fast machines >500MHz)
679 //
680 //usleep(100000000);
681
682 //
683 // Request Target position for this moment
684 //
685 sla.Now();
686
687 //
688 // Request theoretical Position for a time in the future (To+dt) from CPU
689 //
690 sla.SetMjd(sla.CalcMjd()+dt/(60*60*24));
691 ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
692 dest = CorrectTarget(GetSePos(), dummy); // [se]
693
694 //
695 // Request absolute position of rotary encoder from Macs
696 //
697 if (!RequestRePos())
698 break;
699
700 //
701 // distance between (To+dt) and To [re]
702 // position time difference < 5usec
703 // fOffset does the synchronization between the
704 // Shaft- and the rotary encoders
705 //
706 dest *= kGearRatio; // [re]
707 dest -= GetRePos() + fOffset;
708
709 //
710 // Velocity to go [re/min] to reach the right position at time t+dt
711 // correct for the duration of RaDec2AltAz
712 //
713 const ZdAz v = dest*60.0/(dt-(fMac2->GetTime()-sla));
714
715 //
716 // calculate real velocity of future [re/min]
717 // believing the Macs manual '/4' shouldn't be necessary, but it is.
718 //
719 ZdAz vt = v/4;
720 ZdAz vcalc = sla.GetApproxVel(fRaDec) * kGearRatio2*4./60.; // [re/min]
721 LimitSpeed(&vt, vcalc);
722 vt.Round();
723
724 //
725 // check if the drive is fast enough to follow the star
726 //
727 if (vt.Zd()>.9*fMac1->GetVelRes() || vt.Az()>.9*fMac2->GetVelRes())
728 {
729 lout << "Error: Tracking speed faster than 90% of possible maximum velocity." << endl;
730 break;
731 }
732
733 //
734 // Set theoretical velocity (as early after calculation as possible)
735 // Maybe we should attenuate the changes
736 //
737 if (!SetVelocity(vt))
738 break;
739
740 //
741 // Now do 'unnecessary' things
742 //
743 fVelocity = vt/kGearRatio2*4;
744
745//--- const double mjd = fMac2->GetMjd();
746//--- fout << setprecision(15) << setw(17) << mjd*60.*60.*24. << " ";
747//--- fout << setw(4) << vt.Zd() << " ";
748//--- fout << setw(4) << vt.Az() << endl;
749 //
750 // FIXME? Calculate an accuracy for the tracking system?
751 // How good do we reach the calculated position in 'real'
752 // re valus?
753 //
754
755
756 //
757 // Update speed as often as possible.
758 // make sure, that dt is around 10 times larger than the
759 // update time
760 //
761 usleep(50000); // 0.05s
762 }
763
764 fTracking = kFALSE;
765 StopMovement();
766 lout << "Tracking stopped." << endl;
767}
768
769// --------------------------------------------------------------------------
770//
771// Stops the movement of both motors.
772//
773// Sets the status to stopping. Sets the deceleration to 50% of the maximum.
774// stops. Quits the revolution mode and wait for the end of the movement.
775//
776void MCosy::StopMovement()
777{
778 if (!fMac1 || !fMac2)
779 return;
780 //
781 // Set status to stopped
782 //
783 SetStatus(MCosy::kStopping);
784
785 //
786 // set deceleration to 50%
787 //
788 cout << "Stopping positioning..." << endl;
789 fMac1->SetDeceleration(0.5*fMac1->GetVelRes());
790 fMac2->SetDeceleration(0.5*fMac2->GetVelRes());
791
792 //
793 // Stop revolution mode (movement)
794 //
795 cout << "Stopping possibleRPM mode..." << endl;
796 fMac1->SetRpmMode(FALSE);
797 fMac2->SetRpmMode(FALSE);
798
799 //
800 // Wait for the movement to really be finished.
801 //
802 cout << "Waiting for silence..." << endl;
803 WaitForEndMovement();
804
805 //
806 // Check whether everything works fine.
807 //
808 CheckForError();
809 cout << "Movement stopped." << endl;
810}
811
812void *MCosy::Proc(int msg, void *mp)
813{
814 cout << "MCosy::Proc: 0x" << msg << endl;
815 switch (msg)
816 {
817 case WM_WAIT:
818 cout << "Wait for execution of Proc(WM_*, ): done." << endl;
819 return NULL;
820
821 case WM_STOP:
822 StopMovement();
823 return NULL;
824
825 case WM_PRESET:
826 cout << "WM_Preset: start." << endl;
827 if (fZd1) fZd1->SetPreset();
828 if (fZd2) fZd2->SetPreset();
829 if (fAz) fAz->SetPreset();
830 cout << "WM_Preset: done. (return 0xaffe)" << endl;
831 return (void*)0xaffe;
832
833 case WM_CALIB:
834 {
835 cout << "WM_Calib: start." << endl;
836 SlaStars sla;
837 sla.SetMjd2Now();
838
839 RaDec rd = *((RaDec*)mp);
840
841 //RaDec rd(37.94, 89.2644); // POLARIS
842 //RaDec rd(213.915417, 19.1825); // ACTURUS
843
844 cout << "Calibrating to: " << rd.Ra()*24/360 << "h " << rd.Dec() << "°" << endl;
845
846 ZdAz za=sla.CalcZdAz(rd*kDeg2Rad)*16384.0/k2Pi;
847
848 cout << "Calc Zd: " << za.Zd() << " Az: " << za.Az() << endl;
849
850 ZdAz sepos = GetSePos();
851 cout << "Got Zd: " << sepos.Zd() << " Az: " << sepos.Az() << endl;
852
853 if (fZd1)
854 fZd1->SetPreset(za.Zd());
855 if(fZd2)
856 fZd2->SetPreset(-za.Zd());
857 if(fAz)
858 fAz->SetPreset(za.Az());
859
860 cout << "WM_Calib: done. (return 0xaffe)" << endl;
861 }
862 return (void*)0xaffe;
863
864 case WM_TPOINT:
865 {
866 cout << "WM_TPoint: start." << endl;
867 SlaStars sla;
868 sla.SetMjd2Now();
869
870 RaDec rd = *((RaDec*)mp);
871 cout << "TPoint Star: " << rd.Ra()/15 << "h " << rd.Dec() << "°" << endl;
872
873 AltAz za=sla.CalcAltAz(rd*kDeg2Rad)*kRad2Deg;
874
875 cout << " Alt/Az: " << za.Alt() << "° " << za.Az() << "°" << endl;
876 *tpout << za.Az() << " " << za.Alt() << " ";
877
878 ZdAz sepos = GetSePos()*TMath::Pi()*2/16384;;
879 za.Set(TMath::Pi()/2-sepos.Zd(), sepos.Az());
880 za *= kRad2Deg;
881
882 cout << " SE-Pos: " << za.Alt() << "° " << za.Az() << "°" << endl;
883 *tpout << fmod(za.Az()+360, 360) << " " << za.Alt() << endl;
884
885 cout << "WM_TPoint: done. (return 0xaffe)" << endl;
886 }
887 return (void*)0xca1b;
888
889 case WM_POSITION:
890 cout << "WM_Position: start." << endl;
891 {
892 ZdAz dest = *((ZdAz*)mp);
893
894 SetPosition(dest*kDeg2Rad);
895 }
896 cout << "WM_Position: done. (return 0x7777)" << endl;
897 return (void*)0x7777;
898
899 case WM_TRACK:
900 cout << "WM_Track: START" << endl;
901 {
902 RaDec dest = *((RaDec*)mp);
903 TrackPosition(dest*kDeg2Rad);
904 }
905 cout << "WM_Track: done. (return 0x8888)" << endl;
906 return (void*)0x8888;
907
908 case WM_NEWTRACK:
909 cout << "WM_NewTrack: START" << endl;
910 fRaDec = *((RaDec*)mp);
911 cout << "WM_NewTrack: done. (return 0x9999)" << endl;
912 return (void*)0x9999;
913
914 case WM_LOADBENDING:
915 cout << "WM_LoadBending: START" << endl;
916 fBending.Load("bending.txt");
917 cout << "WM_LoadBending: done. (return 0xbe0d)" << endl;
918 return (void*)0xbe0d;
919
920 case WM_RESETBENDING:
921 cout << "WM_ResetBending: START" << endl;
922 fBending.Reset();
923 cout << "WM_ResetBending: done. (return 0xbe0e)" << endl;
924 return (void*)0xbe0e;
925
926 case WM_CALCALTAZ:
927 {
928 cout << endl;
929
930 SlaStars sla;
931 sla.SetMjd2Now();
932
933 XY xy = *((XY*)mp);
934 RaDec rd(xy.X()*15., xy.Y());
935
936 ZdAz a0 = sla.CalcZdAz(rd*kDeg2Rad);
937 ZdAz a1 = fBending(a0);
938 ZdAz se = CorrectTarget(GetSePos(), a1);
939 a0 *= kRad2Deg;
940 a1 *= kRad2Deg;
941 ZdAz a2 = a1*16384/360;
942 cout << "Ra/Dec source: " << xy.X() << "h " << xy.Y() << "°" << endl;
943 cout << "Zd/Az source: " << a0.Zd() << "° " << a0.Az() << "°" << endl;
944 cout << "Zd/Az bended: " << a1.Zd() << "° " << a1.Az() << "°" << endl;
945 cout << "SE bended: " << a2.Zd() << " " << a2.Az() << endl;
946 cout << "SE target: " << se.Zd() << " " << se.Az() << endl;
947 }
948 return (void*)0xa17a;
949
950 case WM_QUIT:
951 cout << "WM_Quit: now." << endl;
952 TerminateApp();
953 cout << "WM_Quit: done." << endl;
954 return (void*)0xaaaa;
955 }
956 cout << "Unknown Msg" << endl;
957 return (void*)0xffffffff;
958}
959
960void *MTTalk::Thread()
961{
962 fCosy->TalkThread();
963 return NULL;
964}
965
966void MCosy::ReadConfig()
967{
968 cout << "Reading configuration file..." << flush;
969 TEnv env(".cosyrc");
970 cout << "done." << endl;
971
972 cout << "Reading gear ratios..." << flush;
973 const Double_t gaz = env.GetValue("Az_GearRatio[U_mot/U_tel]", 1000.0);
974 const Double_t gzd = env.GetValue("Zd_GearRatio[U_mot/U_tel]", 1000.0);
975
976 Double_t resreaz = 0;
977 if (fMac1)
978 resreaz = fMac1->GetRes();
979 else
980 if (fMac3)
981 resreaz = fMac3->GetRes();
982 else
983 resreaz = env.GetValue("Az_ResRE[re/U_mot]", 1500);
984
985 Double_t resrezd = 0;
986 if (fMac2)
987 resrezd = fMac2->GetRes();
988 else
989 resrezd = env.GetValue("Zd_ResRE[re/U_mot]", 1500);
990
991 Double_t ressezd = 0;
992 if (fZd1)
993 ressezd = fZd1->GetPhysRes();
994 else
995 if (fZd2)
996 ressezd = fZd2->GetPhysRes();
997 else
998 ressezd = env.GetValue("Zd_ResSE[se/U_mot]", 16384);
999
1000 Double_t resseaz = 0;
1001 if (fAz)
1002 resseaz = fAz->GetPhysRes();
1003 else
1004 resseaz = env.GetValue("Az_ResSE[se/U_mot]", 16384);
1005
1006 /* WORKAROUND !!!!!!!!!!!!! FIXME !!!!!!!!!!! */
1007 resrezd = 500;
1008 resreaz = 500;
1009
1010 kGearRatio.Set (gzd*resrezd/ressezd, gaz*resreaz/resseaz); //[re/se]
1011 kGearRatio2.Set(gzd*resrezd/360.0, gaz*resreaz/360.0); //[re/deg]
1012 cout << "done." << endl;
1013
1014 cout << "Setting Gear Ratios:" << endl;
1015 cout << "--------------------" << endl;
1016 cout << " X: " << gzd << "*" << resrezd << "/" << ressezd << "=" << kGearRatio.X() << endl;
1017 cout << " Y: " << gaz << "*" << resreaz << "/" << resseaz << "=" << kGearRatio.Y() << endl;
1018}
1019
1020void MCosy::TalkThread()
1021{
1022 if (!(fMac1 && fMac2))
1023 return;
1024
1025 fMac1->ReqPos();
1026 fMac2->ReqPos();
1027
1028 if (fMac3)
1029 {
1030 const int res = fMac3->GetVelRes();
1031
1032 fMac3->SetVelocity(res);
1033 fMac3->SetAcceleration(res);
1034 fMac3->SetDeceleration(res);
1035 fMac3->StartPosSync();
1036 }
1037
1038 fMac1->EnableTimeout(kTRUE, 500);
1039 fMac2->EnableTimeout(kTRUE, 500);
1040
1041 if (!(fZd1 && fZd2 && fAz))
1042 return;
1043
1044 /*
1045 //
1046 // Start the Network
1047 //
1048 cout << "Reading configuration file..." << flush;
1049 TEnv env(".cosyrc");
1050 cout << "done." << endl;
1051
1052 const int res = fMac3->GetVelRes();
1053
1054 fMac3->SetVelocity(res);
1055 fMac3->SetAcceleration(res);
1056 fMac3->SetDeceleration(res);
1057
1058 cout << "Going Home..." << endl;
1059 fMac1->SetHome(250000, env.GetValue("Az_MaxTime2ReachHome[s]", 100));
1060 fMac2->SetHome(250000, env.GetValue("Zd_MaxTime2ReachHome[s]", 100));
1061 PostMsg(WM_PRESET, 0, 0);
1062 PostMsg(WM_WAIT, 0, 0);
1063
1064 fMac1->ReqPos();
1065 fMac2->ReqPos();
1066
1067 //const ZdAz repos=GetRePos();
1068 //cout << "APOS: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
1069
1070 //cout << Deg2AzRE(env.GetValue("MinAz[Deg]", -1.0)) << " < Az < "
1071 //</< Deg2AzRE(env.GetValue("MaxAz[Deg]", +1.0)) << "RE" << endl;
1072 //cout << env.GetValue("MinAz[Deg]", -1.0) << " < Az < "
1073 //<< env.GetValue("MaxAz[Deg]", +1.0) << kDEG << endl;
1074 //cout << Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)) << "RE < Zd < "
1075 //<< Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)) << "RE" << endl;
1076
1077 cout << "Setting up software endswitch..." << flush;
1078 fMac1->SetNegEndswitch(Deg2AzRE(env.GetValue("Az_Min[Deg]", -1.0)));
1079 fMac1->SetPosEndswitch(Deg2AzRE(env.GetValue("Az_Max[Deg]", +1.0)));
1080
1081 fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("Zd_Min[Deg]", -1.0)));
1082 fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("Zd_Max[Deg]", +1.0)));
1083 cout << "done." << endl;
1084
1085 fMac1->EnableTimeout(kTRUE, 500);
1086 fMac2->EnableTimeout(kTRUE, 500);
1087
1088 const Double_t gaz = env.GetValue("Az_GearRatio[U_mot/U_tel]");
1089 const Double_t gzd = env.GetValue("Zd_GearRatio[U_mot/U_tel]");
1090
1091 const Double_t resreaz = env.GetValue("Az_ResRE[re/U_mot]");
1092 const Double_t resrezd = env.GetValue("Zd_ResRE[re/U_mot]");
1093
1094 kGearRatio.Set (gzd*resrezd/RES_SE, gaz*resreaz/RES_SE); //[re/se]
1095 kGearRatio2.Set(gzd*resrezd/360.0, gaz*resreaz/360.0); //[re/deg]
1096
1097 //fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)));
1098 //fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)));
1099 // fMac3->StartVelSync();
1100
1101 //cout << "PostMsg(WM_PRESET)" << endl;
1102 //void *rc =
1103 //cout << hex << "WM_PRESET: ret=" << rc << endl;
1104
1105 //RaDec dest = RaDec(45.0, 30.0)*D2PI/360.0;
1106
1107 //cout << "PostMsg(WM_TRACK)" << endl;
1108 //cout << sizeof(RaDec) << "==" << sizeof(dest) << endl;
1109 //rc=PostMsg(WM_TRACK, &dest, sizeof(dest));
1110 //cout << "DEST killed." << endl;
1111
1112 // AltAz dest = AltAz(45.0, 30.0);
1113 // double ra, dec;
1114 // slaDaf2r( 71, 0, 0, &ra, &status); // 0 WARNING: RANGE
1115 // slaDaf2r( 89, 0, 0, &dec, &status); // 49
1116 // cout << "Start tracking: Ra: " << Rad2Deg(ra) << kDEG << " Dec: " << Rad2Deg(dec) << kDEG << endl;
1117
1118 // dest = AltAz(-46.0, 210);
1119 // SetPosition(dest);
1120 */
1121 SlaStars sla;
1122 while (1)
1123 {
1124 //
1125 // wait until a tracking session is started
1126 //
1127 while (!fTracking)
1128 usleep(1);
1129
1130//--- ofstream fout("log/cosy.err");
1131//--- fout << "Tracking:";
1132//--- fout << " Ra: " << Rad2Deg(fRaDec.Ra()) << "\x9c ";
1133//--- fout << "Dec: " << Rad2Deg(fRaDec.Dec()) << "\x9c" << endl << endl;
1134//--- fout << " MjdZd/10ms ErrZd/re";
1135//--- fout << " MjdAz/10ms ErrAd/re" << endl;
1136
1137 ZdAz old;
1138 ZdAz ist;
1139
1140 ZdAz sollzd;
1141 ZdAz sollaz;
1142
1143 ZdAz istre = -fOffset; // [re]
1144 ZdAz time;
1145
1146 //
1147 // only update fTrackingError while tracking
1148 //
1149 bool phca1=false;
1150 bool phca2=false;
1151 bool phcaz=false;
1152
1153 while (fTracking)
1154 {
1155 //
1156 // Make changes (eg wind) smoother - attenuation of control function
1157 //
1158 const float weight = 1.; //0.3;
1159
1160 //
1161 // This is the time constant which defines how fast
1162 // you correct for external influences (like wind)
1163 //
1164 fZd1->ResetPosHasChanged();
1165 fZd2->ResetPosHasChanged();
1166 fAz->ResetPosHasChanged();
1167 do
1168 {
1169 phca1 = fZd1->PosHasChanged();
1170 phca2 = fZd2->PosHasChanged();
1171 phcaz = fAz->PosHasChanged();
1172 usleep(1);
1173 } while (!phca1 && !phca2 && !phcaz && fTracking);
1174
1175 //---usleep(100000); // 0.1s
1176
1177 //
1178 // get position, where we are
1179 //
1180 old = ist;
1181 ist = GetSePos(); // [se]
1182
1183 //
1184 // if the position didn't change continue
1185 //
1186 /*---
1187 if ((int)ist.Zd() == (int)old.Zd() &&
1188 (int)ist.Az() == (int)old.Az())
1189 continue;
1190 */
1191 istre = GetRePosPdo();
1192
1193 //
1194 // Get time from last shaftencoder position change (position: ist)
1195 // FIXME: I cannot take the avarage
1196 //
1197 time.Zd((fZd1->GetMjd()+fZd2->GetMjd())/2.0);
1198 time.Az(fAz->GetMjd());
1199
1200 //
1201 // if Shaftencoder changed position
1202 // calculate were we should be
1203 //
1204 if (phca1 || phca2 /*(int)ist.Zd() != (int)old.Zd()*/)
1205 {
1206 sla.SetMjd(time.Zd());
1207
1208 ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
1209 sollzd = CorrectTarget(ist, dummy); // [se]
1210
1211 fOffset.Zd(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight);
1212 }
1213
1214 if (phcaz /*(int)ist.Az() != (int)old.Az()*/)
1215 {
1216 sla.SetMjd(time.Az());
1217
1218 ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
1219 sollaz = CorrectTarget(ist, dummy); // [se]
1220
1221 fOffset.Az(fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight);
1222 }
1223
1224 fTrackingError.Set((ist.Zd()-sollzd.Zd())*kGearRatio.X(),
1225 (ist.Az()-sollaz.Az())*kGearRatio.Y());
1226
1227//--- fout << setprecision(15) << setw(17) << time.Zd()*60.*60.*24. << " ";
1228//--- fout << setprecision(5) << setw(7) << fTrackingError.Zd() << " ";
1229//--- fout << setprecision(15) << setw(17) << time.Az()*60.*60.*24. << " ";
1230//--- fout << setprecision(5) << setw(7) << fTrackingError.Az() << endl;
1231 }
1232
1233//--- fout << endl << endl;
1234 }
1235}
1236
1237Bool_t MCosy::HandleTimer(TTimer *t)
1238{
1239 //
1240 // Update Gui, foremer MTGui.
1241 //
1242 if (fZd1) fZd1->DisplayVal();
1243 if (fZd2) fZd2->DisplayVal();
1244 if (fAz) fAz->DisplayVal();
1245
1246 ZdAz seist = GetSePos()*2*TMath::Pi()/16384; // [se]
1247 ZdAz bendist = fBending.CorrectBack(seist);
1248
1249 fWin->Update(bendist*(360.0/2/TMath::Pi()), fTrackingError/kGearRatio2,
1250 fVelocity, fOffset/*/kGearRatio2*/,
1251 fStatus);
1252
1253 return kTRUE;
1254}
1255
1256
1257// --------------------------------------------------------------------------
1258//
1259// Start the work of the application:
1260//
1261// Start the Can-Network.
1262// Start the MCosy::TalkThread thread.
1263// turn on the gui update
1264//
1265void MCosy::Start()
1266{
1267 // Don't call this function twice!
1268 Network::Start();
1269
1270 if (fMac1)
1271 if (fMac1->IsZombieNode()) { delete fMac1; fMac1=NULL; }
1272 if (fMac2)
1273 if (fMac2->IsZombieNode()) { delete fMac2; fMac2=NULL; }
1274 if (fMac3)
1275 if (fMac3->IsZombieNode()) { delete fMac3; fMac3=NULL; }
1276
1277 if (fZd1)
1278 if (fZd1->IsZombieNode()) { delete fZd1; fZd1=NULL; }
1279 else fZd1->SetDisplay(fWin->GetLabel2());
1280
1281 if (fZd2)
1282 if (fZd2->IsZombieNode()) { delete fZd2; fZd2=NULL; }
1283 else fZd2->SetDisplay(fWin->GetLabel3());
1284
1285 if (fAz)
1286 if (fAz->IsZombieNode()) { delete fAz; fAz=NULL; }
1287 else fAz->SetDisplay(fWin->GetLabel1());
1288
1289 ReadConfig();
1290
1291 lout << "- Starting TX Thread." << endl;
1292 fTTalk = new MTTalk(this);
1293
1294 lout << "- Starting GUI update." << endl;
1295 fUpdateGui->TurnOn();
1296 // fTGui = new MTGui(this);
1297}
1298
1299// --------------------------------------------------------------------------
1300//
1301// Start the work of the application:
1302//
1303// Turn of the gui update
1304// stop the MCosy::TalkThread thread.
1305// Stop the network
1306//
1307void MCosy::Stop()
1308{
1309
1310 lout << "- Stopping GUI update." << endl;
1311 fUpdateGui->TurnOff();
1312 lout << "- GUI Update stopped." << endl;
1313
1314 delete fTTalk;
1315 lout << "- TX Thread stopped." << endl;
1316
1317 Network::Stop();
1318}
1319
1320// --------------------------------------------------------------------------
1321//
1322// Disable the synchronization by using a negative CAN Id for id2.
1323//
1324void MCosy::Constructor(Int_t id1, Int_t id2, Int_t id3,
1325 Int_t id4, Int_t id5, Int_t id6)
1326{
1327 //
1328 // Create Nodes
1329 //
1330 lout << "- Setting up network." << endl;
1331
1332 fMac1=new Macs(id1, "Mac/Az", lout);
1333 fMac2=new Macs(id3, "Mac/Zd", lout);
1334 if (id2>=0)
1335 fMac3=new Macs(id2, "Mac/Az-Sync", lout);
1336
1337 fZd1=new ShaftEncoder(id4, "SE/Zd1", lout);
1338 fZd2=new ShaftEncoder(id5, "SE/Zd2", lout);
1339 fAz =new ShaftEncoder(id6, "SE/Az", lout);
1340
1341 lout << "- Connecting devices to network." << endl;
1342
1343 //
1344 // Connect the devices to the network
1345 //
1346 SetNode(fMac1);
1347 SetNode(fMac2);
1348 if (id2>=0)
1349 SetNode(fMac3);
1350 SetNode(fZd1);
1351 SetNode(fZd2);
1352 SetNode(fAz);
1353
1354 //
1355 // Create Gui Event timer and Gui
1356 //
1357 lout << "- Initializing GUI Timer." << endl;
1358 fUpdateGui = new TTimer(this, 100); // 100ms
1359
1360 lout << "- Starting GUI." << endl;
1361 fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
1362
1363 fAz->SetDisplay(fWin->GetLabel1());
1364 fZd1->SetDisplay(fWin->GetLabel2());
1365 fZd2->SetDisplay(fWin->GetLabel3());
1366
1367 lout.SetOutputGui(fWin->GetLog(), kTRUE);
1368}
1369
1370void MCosy::ConstructorSE(Int_t id4, Int_t id5, Int_t id6)
1371{
1372 //
1373 // Create Nodes
1374 //
1375 lout << "- Setting up network." << endl;
1376
1377 fZd1=new ShaftEncoder(id4, "SE/Zd1", lout);
1378 fZd2=new ShaftEncoder(id5, "SE/Zd2", lout);
1379 fAz =new ShaftEncoder(id6, "SE/Az", lout);
1380
1381 lout << "- Connecting devices to network." << endl;
1382
1383 //
1384 // Connect the devices to the network
1385 //
1386 SetNode(fZd1);
1387 SetNode(fZd2);
1388 SetNode(fAz);
1389
1390 //
1391 // Create Gui Event timer and Gui
1392 //
1393 lout << "- Initializing GUI Timer." << endl;
1394 fUpdateGui = new TTimer(this, 100); // 100ms
1395
1396 lout << "- Starting GUI." << endl;
1397 fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
1398
1399 fAz->SetDisplay(fWin->GetLabel1());
1400 fZd1->SetDisplay(fWin->GetLabel2());
1401 fZd2->SetDisplay(fWin->GetLabel3());
1402
1403 lout.SetOutputGui(fWin->GetLog(), kTRUE);
1404}
1405
1406void MCosy::ConstructorDemo()
1407{
1408 //
1409 // Create Nodes
1410 //
1411 lout << "- Setting up network." << endl;
1412
1413 //
1414 // Create Gui Event timer and Gui
1415 //
1416 lout << "- Initializing GUI Timer." << endl;
1417 fUpdateGui = new TTimer(this, 100); // 100ms
1418
1419 lout << "- Starting GUI." << endl;
1420 fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
1421
1422 lout.SetOutputGui(fWin->GetLog(), kTRUE);
1423}
1424
1425MCosy::MCosy(int mode, const char *dev, const int baud, MLog &out)
1426: Network(dev, baud, out), fZd1(0), fZd2(0), fAz(0), fMac1(0), fMac2(0), fMac3(0), fTracking(kFALSE)
1427{
1428 TEnv env(".cosyrc");
1429 const Int_t id1 = env.GetValue("Az_Id-MAC1", 1); //1
1430 const Int_t id2 = env.GetValue("Az_Id-MAC2", 2); //2
1431 const Int_t id3 = env.GetValue("Zd_Id-MAC", 3); //3
1432 const Int_t id4 = env.GetValue("Zd_Id-SE1", 4); //4
1433 const Int_t id5 = env.GetValue("Zd_Id-SE2", 5); //5
1434 const Int_t id6 = env.GetValue("Az_Id-SE", 6); //6
1435
1436 lout << "- Program in ";
1437 switch (mode)
1438 {
1439 case 0:
1440 lout << "<<Stanard mode>>" << endl;
1441 Constructor(id1, id2, id3, id4, id5, id6);
1442 break;
1443 case 1:
1444 lout << "<<SE mode>>" << endl;
1445 ConstructorSE(id4, id5, id6);
1446 break;
1447 default:
1448 lout << "<<Demo mode>>" << endl;
1449 ConstructorDemo();
1450 }
1451
1452 int i=0;
1453 char name[100];
1454 while (1)
1455 {
1456 sprintf(name, "/home/tbretz/TPoint/tpoint%03d.txt", i++);
1457 cout << "Testing: " << name << endl;
1458 if (gSystem->AccessPathName(name, kFileExists))
1459 break;
1460 }
1461
1462 Timer time;
1463 time.Now();
1464
1465 tpout = new ofstream(name);
1466 *tpout << "Magic Model TPOINT data file" << endl;
1467 *tpout << ": ALTAZ" << endl;
1468 *tpout << "49 48 0 ";
1469 *tpout << time.Year() << " " << time.Month() << " " << time.Day() << " ";
1470 *tpout << /*"20 1013.25 300 0.5 0.55 0.0065" <<*/ endl;
1471 // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
1472}
1473
1474void MCosy::TerminateApp()
1475{
1476 cout << "MCosy::TerminateApp()" << endl;
1477/*
1478 Int_t rc;
1479 TGMessageBox msg(this, gClient->GetRoot(),
1480 "Information",
1481 "Cosy is shutting down the system - this may take wa while!",
1482 kMBIconExclamation,
1483 kMBOK, //kMBClose
1484 &rc, 0);
1485*/
1486
1487 lout.DisableOutputDevice(MLog::eGui);
1488 lout.SetOutputGui(NULL, kFALSE);
1489
1490 gApplication->Terminate(0);
1491}
1492
1493MCosy::~MCosy()
1494{
1495 *tpout << "END" << endl;
1496 delete tpout;
1497
1498 cout << "Deleting GUI timer." << endl;
1499
1500 delete fUpdateGui;
1501
1502 cout << "Deleting Nodes." << endl;
1503
1504 if (fAz) delete fAz;
1505 if (fZd1) delete fZd1;
1506 if (fZd2) delete fZd2;
1507 if (fMac1) delete fMac1;
1508 if (fMac2) delete fMac2;
1509 if (fMac3) delete fMac3;
1510
1511 cout << "Deleting MGCosy." << endl;
1512
1513 lout.DisableOutputDevice(MLog::eGui);
1514
1515 delete fWin;
1516
1517 cout << "MGCosy destructed." << endl;
1518}
Note: See TracBrowser for help on using the repository browser.