source: trunk/MagicSoft/Cosy/MCosy.cc@ 959

Last change on this file since 959 was 921, checked in by tbretz, 23 years ago
*** empty log message ***
  • Property svn:executable set to *
File size: 22.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
24typedef struct tm tm_t;
25
26#define GEAR_RATIO_ALT 75.55 // 75.25 VERY IMPORTANT! unit=RE/SE
27#define GEAR_RATIO_AZ 179.8 // VERY IMPORTANT! unit=RE/SE
28
29const XY kGearRatio(GEAR_RATIO_ALT, GEAR_RATIO_AZ);
30const XY kGearRatio2(GEAR_RATIO_ALT*16384.0/360.0, GEAR_RATIO_AZ*16384.0/360.0);
31
32double Rad2SE(double rad)
33{
34 return 16384.0/D2PI*rad;
35}
36
37double Rad2ZdRE(double rad)
38{
39 return 16384.0/D2PI*rad*kGearRatio.X();
40}
41
42double Rad2AzRE(double rad)
43{
44 return 16384.0/D2PI*rad*kGearRatio.Y();
45}
46
47double Deg2ZdRE(double rad)
48{
49 return rad*kGearRatio2.X();
50}
51
52double Deg2AzRE(double rad)
53{
54 return rad*kGearRatio2.Y();
55}
56
57ZdAz MCosy::CorrectTarget(const ZdAz &src, const ZdAz &dst)
58{
59 // CorrectTarget [se]
60
61 // src [se]
62 // dst [rad]
63
64 // fAltMax = 70
65 // fAltMin = -105/110
66 // fAzMin = -355
67 // fAzMax = 355
68
69 ZdAz source = src * 360.0/16384.0;
70 ZdAz dest = dst * 360.0/D2PI;
71
72 if (dest.Zd()>-1e-6 && dest.Zd()<1e-6)
73 return dst*(16384.0/D2PI);
74
75 const float fZdMin = -67;
76 const float fZdMax = 67;
77 const float fAzMin = -29;
78 const float fAzMax = 423;
79
80 //
81 // This corrects to target for the shortest distance, not for the fastest move!
82 //
83 ZdAz s = source-dest;
84
85 float min = s.Sqr();
86
87 //
88 // Is it enought to search inside one revolution?
89 //
90 ZdAz ret = dest;
91
92 for (int i=-5; i<5+1; i++)
93 {
94 const ZdAz p(i%2 ? -dest.Zd() : dest.Zd(), dest.Az() - i*180);
95
96 //
97 // Range Check
98 //
99 if (p.Zd()<fZdMin || p.Zd()>fZdMax)
100 continue;
101
102 if (p.Az()<fAzMin || p.Az()>fAzMax)
103 continue;
104
105 //
106 // Calculate distance
107 //
108 s = source-p;
109
110 const float dist = s.Sqr();
111
112 if (dist > min)
113 continue;
114
115 //
116 // New shortest distance
117 //
118 ret = p;
119 min = dist;
120 }
121 return ret*(16384.0/360.0);
122}
123
124
125ZdAz MCosy::GetSePos()
126{
127 const int p0 = fAlt1->GetPos();
128 const int p1 = fAlt2->GetPos();
129 const int p2 = fAz->GetPos();
130
131 const int a0 = p0; //p0>8192?p0-16384:p0;
132 const int a1 = p1; //p1>8192?p1-16384:p1;
133 const int a2 = p2; //p2>8192?p2-16384:p2;
134
135 //
136 // interpolate shaft encoder positions
137 //
138 const float a = (float)(a0-a1)/2;
139
140 //
141 // calculate 'regelabweichung'
142 //
143 return ZdAz(a, a2);
144}
145
146ZdAz MCosy::GetRePos()
147{
148 return ZdAz(fMac2->GetPos(), fMac1->GetPos());
149}
150
151ZdAz MCosy::GetRePosPdo()
152{
153 return ZdAz(fMac2->GetPdoPos(), fMac1->GetPdoPos());
154}
155
156void MCosy::SetPosVelocity(const Float_t ratio, Float_t vel, Float_t acc)
157{
158 //
159 // Set velocities
160 //
161 const int vr = fMac1->GetVelRes();
162
163 vel *= vr;
164 acc *= vr;
165
166 if (ratio <1)
167 {
168 fMac1->SetVelocity(vel);
169 fMac1->SetAcceleration(acc);
170 fMac1->SetDeceleration(acc);
171
172 fMac2->SetVelocity(vel*ratio);
173 fMac2->SetAcceleration(acc*ratio);
174 fMac2->SetDeceleration(acc*ratio);
175 }
176 else
177 {
178 fMac1->SetVelocity(vel/ratio);
179 fMac1->SetAcceleration(acc/ratio);
180 fMac1->SetDeceleration(acc/ratio);
181
182 fMac2->SetVelocity(vel);
183 fMac2->SetAcceleration(acc);
184 fMac2->SetDeceleration(acc);
185 }
186}
187
188void MCosy::DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2)
189{
190 SetStatus(kMoving);
191
192 if (axe1) fMac2->StartRelPos(rd.Zd());
193 if (axe2) fMac1->StartRelPos(rd.Az());
194
195 cout << "Waiting for positioning..." << flush;
196
197 WaitForEndMovement();
198
199 cout << "done." << endl;
200}
201
202void MCosy::CheckForError()
203{
204 if (!HasError())
205 {
206 SetStatus(kStopped);
207 return;
208 }
209
210 SetStatus(kError);
211 fMac1->HandleError();
212 fMac2->HandleError();
213 if (HasError())
214 return;
215
216 SetStatus(kStopped);
217}
218
219int MCosy::SetPosition(const ZdAz &dst) // [rad]
220{
221 // FIXME: Correct by fOffset ?
222
223 //
224 // Calculate new target position (shortest distance to go)
225 //
226 const ZdAz src = GetSePos();
227 const ZdAz dest = CorrectTarget(src, dst);
228
229 lout << "Positioning to Target..." << endl;
230 //cout << "Source Zd: " << src.Zd() << "se Az:" << src.Az() << "se" << endl;
231 //cout << "Destination Zd: " << Rad2SE(dst.Zd()) << "se Az:" << Rad2SE(dst.Az()) << "se" << endl;
232 //cout << "Shortest Dest Zd: " << dest.Zd() << "se Az:" << dest.Az() << "se" << endl;
233
234 for (int i=0; i<10 && !StopWaitingForSDO(); i++)
235 {
236 //
237 // Get Shaft Encoder Positions
238 //
239 const ZdAz p=GetSePos();
240
241 //
242 // calculate control deviation and rounded cd
243 //
244 ZdAz rd = dest-p; // [se]
245
246 ZdAz cd = rd; // [se]
247 cd.Round();
248
249 //
250 // Check if there is a control deviation on the axis
251 //
252 const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
253 const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
254
255 //
256 // check if we reached the correct position already
257 //
258 if (!cdzd && !cdaz)
259 {
260 lout << "Positioning done with " << i << "manuvers." << endl;
261 return TRUE;
262 }
263
264 //
265 // change units from se to re
266 //
267 rd *= kGearRatio; // [re]
268
269 //
270 // Initialize Velocities so that we reach both positions
271 // at the same time
272 //
273 if (i)
274 SetPosVelocity(1.0, 0.1, 0.1);
275 else
276 SetPosVelocity(fabs(rd.Ratio()), 0.9, 0.5);
277
278 rd.Round();
279
280 /*
281 cout << " + " << cdzd << " " << cdaz << endl;
282 cout << " + APOS: Zd=" << setw(6) << p.Zd() << "se Az=" << setw(6) << p.Az() << "se" << endl;
283 cout << " + dZd=" << setw(6) << cd.Zd() << "se dAz=" << setw(6) << cd.Az() << "se" << endl;
284 cout << " + dZd=" << setw(6) << rd.Zd() << "re dAz=" << setw(6) << rd.Az() << "re" << endl;
285 */
286
287 //
288 // repositioning (relative)
289 //
290 DoRelPos(rd, cdzd, cdaz);
291 }
292
293 StopMovement();
294 lout << "Warning: Requested position not reached." << endl;
295 return FALSE;
296}
297
298Bool_t MCosy::RequestRePos()
299{
300
301 fMac2->RequestSDO(0x6004);
302 fMac1->RequestSDO(0x6004);
303 WaitForSdos();
304 if (!StopWaitingForSDO())
305 return kTRUE;
306
307 if (HasError())
308 lout << "Error #6004 (requesting re pos from Macs) happened." << endl;
309
310 return kFALSE;
311}
312
313Bool_t MCosy::SetVelocity(ZdAz v)
314{
315 fMac2->SendSDO(0x3006, 1, (LWORD_t)v.Zd()); // SetRpmVelocity [re/min]
316 fMac1->SendSDO(0x3006, 1, (LWORD_t)v.Az()); // SetRpmVelocity [re/min]
317 WaitForSdos();
318 if (!StopWaitingForSDO())
319 return kTRUE;
320
321 if (HasError())
322 lout << "Error #3006 (setting velocity of Macs) happened." << endl;
323
324 return kFALSE;
325}
326
327void MCosy::InitTracking()
328{
329 //
330 // Start revolution mode
331 //
332 fMac2->SetAcceleration(0.90*fMac2->GetVelRes());
333 fMac2->SetDeceleration(0.90*fMac2->GetVelRes());
334
335 fMac1->SetAcceleration(0.90*fMac1->GetVelRes());
336 fMac1->SetDeceleration(0.90*fMac1->GetVelRes());
337
338 SetStatus(kMoving | kTracking);
339
340 fMac2->SetRpmMode(TRUE);
341 fMac1->SetRpmMode(TRUE);
342}
343
344void MCosy::LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const
345{
346 //
347 // How to limit the speed. If the wind comes and blowes
348 // we cannot forbid changing of the sign. But on the other hand
349 // we don't want fast changes!
350 //
351
352 ULong_t vrzd = fMac1->GetVelRes();
353 ULong_t vraz = fMac2->GetVelRes();
354
355#define sgn(x) (x<0?-1:1)
356
357 const Float_t limit = 0.25;
358
359 if (sgn(vt->Az()) != sgn(vcalc.Az()) &&
360 fabs(vt->Az()) < limit*fabs(vcalc.Az()))
361 vt->Az(0);
362 else
363 if (fabs(vt->Az()) > 0.9*vraz)
364 vt->Az(0.9*vraz*sgn(vt->Az()));
365
366 if (sgn(vt->Zd()) != sgn(vcalc.Zd()) &&
367 fabs(vt->Zd()) < limit*fabs(vcalc.Zd()))
368 vt->Zd(0);
369 else
370 if (fabs(vt->Zd()) > 0.9*vrzd)
371 vt->Zd(0.9*vrzd*sgn(vt->Zd()));
372}
373
374void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
375{
376 SlaStars sla;
377
378 //
379 // Position to actual position
380 //
381 sla.SetMjd2Now();
382 ZdAz dest = sla.CalcZdAz(dst);
383
384 if (!SetPosition(dest))
385 {
386 lout << "Error: Cannot start tracking, positioning failed." << endl;
387 return;
388 }
389
390 //
391 // calculate offset from present se position
392 //
393 const ZdAz sepos = GetSePos()*kGearRatio;
394
395 if (!RequestRePos())
396 return;
397
398 //
399 // Estimate Offset before starting to track
400 //
401 fOffset = sepos-GetRePos();
402
403 /*
404 cout << "Sepos: " << sepos.Zd() << "re, " << sepos.Az() << "re" << endl;
405 cout << "Repos: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
406 cout << "Offset: " << fOffset.Zd() << "re, " << fOffset.Az() << "re" << endl;
407 */
408
409 //
410 // Init accelerations and Rpm Mode
411 //
412 InitTracking();
413
414 lout << "Start tracking:";
415 lout << " Ra: " << Rad2Deg(dst.Ra()) << "\xb0 ";
416 lout << "Dec: " << Rad2Deg(dst.Dec()) << "\xb0" << endl;
417
418 //
419 // Initialize Tracker (slalib or starguider)
420 //
421 fRaDec = dst;
422 fTracking = kTRUE;
423
424 ofstream fout("cosy.pos");
425 fout << "Tracking:";
426 fout << " Ra: " << Rad2Deg(dst.Ra()) << "\x9c ";
427 fout << "Dec: " << Rad2Deg(dst.Dec()) << "\x9c" << endl << endl;
428 fout << " Mjd/10ms V/re/min/4" << endl;
429
430 //
431 // We want to reach the theoretical position exactly in about 0.5s
432 //
433 const float dt = 1; // 1 second
434 while (!StopWaitingForSDO())
435 {
436 //
437 // Request Target position for this moment
438 //
439 sla.Now();
440
441 //
442 // Request theoretical Position for a time in the future (To+dt) from CPU
443 //
444 sla.SetMjd(sla.CalcMjd()+dt/(60*60*24));
445 dest = CorrectTarget(GetSePos(), sla.CalcZdAz(dst)); // [se]
446
447 ZdAz vcalc = sla.GetApproxVel(dst) * kGearRatio2*4./60.; // [re/min]
448
449 //
450 // Request absolute position of rotary encoder from Macs
451 //
452 if (!RequestRePos())
453 break;
454
455 //
456 // distance between (To+dt) and To [re]
457 // position time difference < 5usec
458 // fOffset does the synchronization between the
459 // Shaft- and the rotary encoders
460 //
461 dest *= kGearRatio; // [re]
462 dest -= GetRePos() + fOffset;
463
464 //
465 // Velocity to go [re/min] to reach the right position at time t+dt
466 // correct for the duration of RaDec2AltAz
467 //
468 const ZdAz v = dest*60.0/(dt-(fMac2->GetTime()-sla));
469
470 //
471 // calculate real velocity of future [re/min]
472 // believing the Macs manual '/4' shouldn't be necessary, but it is.
473 //
474 ZdAz vt = v/4;
475 LimitSpeed(&vt, vcalc);
476 vt.Round();
477
478 //
479 // check if the drive is fast enough to follow the star
480 //
481 if (vt.Zd()>.9*fMac1->GetVelRes() || vt.Az()>.9*fMac2->GetVelRes())
482 {
483 lout << "Error: Tracking speed faster than 90% of possible maximum velocity." << endl;
484 break;
485 }
486
487 //
488 // Set theoretical velocity (as early after calculation as possible)
489 // Maybe we should attenuate the changes
490 //
491 if (!SetVelocity(vt))
492 break;
493
494 //
495 // Now do 'unnecessary' things
496 //
497 fVelocity = vt/kGearRatio2*4;
498
499 const double mjd = fMac2->GetMjd();
500 fout << setprecision(15) << setw(15) << mjd*60.*60.*24. << " ";
501 fout << setw(4) << vt.Zd() << " ";
502 fout << setw(4) << vt.Az() << endl;
503 //
504 // FIXME? Calculate an accuracy for the tracking system?
505 // How good do we reach the calculated position in 'real'
506 // re valus?
507 //
508
509
510 //
511 // Update speed as often as possible.
512 // make sure, that dt is around 10 times larger than the
513 // update time
514 //
515 // usleep(50000); // 0.05s
516 }
517
518 fTracking = kFALSE;
519 StopMovement();
520 lout << "Tracking stopped." << endl;
521}
522
523int MCosy::IsPositioning() const
524{
525 return (fMac1->IsPositioning() || fMac2->IsPositioning()) && !StopWaitingForSDO();
526}
527
528void MCosy::WaitForEndMovement()
529{
530 WaitForSdos();
531
532 while (IsPositioning())
533 usleep(1);
534}
535
536void MCosy::StopMovement()
537{
538 SetStatus(kStopping);
539
540 cout << "Stopping positioning..." << endl;
541 fMac1->SetDeceleration(0.5*fMac1->GetVelRes());
542 fMac2->SetDeceleration(0.5*fMac2->GetVelRes());
543
544 cout << "Stoping possible RPM mode..." << endl;
545 fMac1->SetRpmMode(FALSE);
546 fMac2->SetRpmMode(FALSE);
547
548 cout << "Waiting for silence..." << endl;
549 WaitForEndMovement();
550
551 CheckForError();
552
553 cout << "Movement stopped." << endl;
554}
555
556void *MCosy::Proc(int msg, void *mp)
557{
558 switch (msg)
559 {
560 case WM_WAIT:
561 cout << "Wait for execution of Proc(WM_*, ): done." << endl;
562 return NULL;
563
564 case WM_STOP:
565 StopMovement();
566 return NULL;
567
568 case WM_PRESET:
569 cout << "WM_Preset: start." << endl;
570 fAlt1->SetPreset();
571 fAlt2->SetPreset();
572 fAz->SetPreset();
573 cout << "WM_Preset: done. (return 0xaffe)" << endl;
574 return (void*)0xaffe;
575
576 case WM_POLARIS:
577 {
578 cout << "WM_Polaris: start." << endl;
579 SlaStars sla;
580 sla.SetMjd2Now();
581
582 RaDec rd(37.94, 89.2644);
583 ZdAz za=sla.CalcZdAz(rd*D2PI/360.0)*16384.0/D2PI;
584
585 cout << "Calc Zd: " << za.Zd() << " Az: " << za.Az() << endl;
586
587 ZdAz sepos = GetSePos();
588 cout << "Got Zd: " << sepos.Zd() << " Az: " << sepos.Az() << endl;
589
590 fAlt1->SetPreset(za.Zd());
591 fAlt2->SetPreset(-za.Zd());
592 fAz->SetPreset(za.Az());
593
594 cout << "WM_Polaris: done. (return 0xaffe)" << endl;
595 }
596 return (void*)0xaffe;
597
598 case WM_POSITION:
599 cout << "WM_Position: start." << endl;
600 {
601 ZdAz dest = *((ZdAz*)mp);
602
603 SetPosition(dest*D2PI/360.0);
604 }
605 cout << "WM_Position: done. (return 0x7777)" << endl;
606 return (void*)0x7777;
607
608 case WM_TRACK:
609 cout << "WM_Track: START" << endl;
610 {
611 RaDec dest = *((RaDec*)mp);
612 TrackPosition(dest*D2PI/360.0);
613 }
614 cout << "WM_Track: done. (return 0x8888)" << endl;
615 return (void*)0x8888;
616
617 case WM_QUIT:
618 cout << "WM_Quit: now." << endl;
619 TerminateApp();
620 cout << "WM_Quit: done." << endl;
621 return (void*)0x9999;
622 }
623 cout << "Unknown Msg" << endl;
624 return (void*)0xffffffff;
625}
626
627void *MTTalk::Thread()
628{
629 fCosy->TalkThread();
630 return NULL;
631}
632
633void MCosy::TalkThread()
634{
635 //
636 // Start the Network
637 //
638 cout << "Reading configuration file..." << flush;
639 TEnv env(".cosyrc");
640 cout << "done." << endl;
641
642 const int res = fMac3->GetVelRes();
643
644 fMac3->SetVelocity(res);
645 fMac3->SetAcceleration(res);
646 fMac3->SetDeceleration(res);
647
648 fMac3->StartPosSync();
649
650 cout << "Going Home..." << endl;
651 fMac1->SetHome(250000, env.GetValue("Az_MaxTime2ReachHome[s]", 100));
652 fMac2->SetHome(250000, env.GetValue("Zd_MaxTime2ReachHome[s]", 100));
653 PostMsg(WM_PRESET, 0, 0);
654 PostMsg(WM_WAIT, 0, 0);
655
656 fMac1->ReqPos();
657 fMac2->ReqPos();
658
659 //const ZdAz repos=GetRePos();
660 //cout << "APOS: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
661
662 /*
663 cout << Deg2AzRE(env.GetValue("MinAz[Deg]", -1.0)) << " < Az < "
664 << Deg2AzRE(env.GetValue("MaxAz[Deg]", +1.0)) << "RE" << endl;
665 cout << env.GetValue("MinAz[Deg]", -1.0) << " < Az < "
666 << env.GetValue("MaxAz[Deg]", +1.0) << kDEG << endl;
667 cout << Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)) << "RE < Zd < "
668 << Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)) << "RE" << endl;
669 */
670
671 cout << "Setting up software endswitch..." << flush;
672 fMac1->SetNegEndswitch(Deg2AzRE(env.GetValue("Az_Min[Deg]", -1.0)));
673 fMac1->SetPosEndswitch(Deg2AzRE(env.GetValue("Az_Max[Deg]", +1.0)));
674
675 fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("Zd_Min[Deg]", -1.0)));
676 fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("Zd_Max[Deg]", +1.0)));
677 cout << "done." << endl;
678
679/*
680 fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)));
681 fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)));
682*/
683// fMac3->StartVelSync();
684/*
685 cout << "PostMsg(WM_PRESET)" << endl;
686 void *rc =
687 cout << hex << "WM_PRESET: ret=" << rc << endl;
688
689 RaDec dest = RaDec(45.0, 30.0)*D2PI/360.0;
690
691 cout << "PostMsg(WM_TRACK)" << endl;
692 cout << sizeof(RaDec) << "==" << sizeof(dest) << endl;
693 rc=PostMsg(WM_TRACK, &dest, sizeof(dest));
694 cout << "DEST killed." << endl;
695*/
696 // AltAz dest = AltAz(45.0, 30.0);
697 // double ra, dec;
698 // slaDaf2r( 71, 0, 0, &ra, &status); // 0 WARNING: RANGE
699 // slaDaf2r( 89, 0, 0, &dec, &status); // 49
700 // cout << "Start tracking: Ra: " << Rad2Deg(ra) << kDEG << " Dec: " << Rad2Deg(dec) << kDEG << endl;
701
702 // dest = AltAz(-46.0, 210);
703 // SetPosition(dest);
704
705 SlaStars sla;
706 while (1)
707 {
708 //
709 // wait until a tracking session is started
710 //
711 while (!fTracking && !fTTalk->HasStopFlag())
712 usleep(1);
713
714 if (fTTalk->HasStopFlag())
715 break;
716
717 ofstream fout("cosy.err");
718 fout << "Tracking:";
719 fout << " Ra: " << Rad2Deg(fRaDec.Ra()) << "\x9c ";
720 fout << "Dec: " << Rad2Deg(fRaDec.Dec()) << "\x9c" << endl << endl;
721 fout << " MjdZd/10ms ErrZd/re";
722 fout << " MjdAz/10ms ErrAd/re" << endl;
723
724 ZdAz old;
725 ZdAz ist;
726
727 ZdAz sollzd;
728 ZdAz sollaz;
729
730 ZdAz istre = -fOffset; // [re]
731 ZdAz time;
732
733 //
734 // only update fTrackingError while tracking
735 //
736 while (fTracking && !fTTalk->HasStopFlag())
737 {
738 //
739 // Make changes (eg wind) smoother - attenuation of control function
740 //
741 const float weight = 0.3;
742
743 ZdAz offset(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight,
744 fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight);
745
746 fOffset = offset;
747
748 //
749 // This is the time constant which defines how fast
750 // you correct for external influences (like wind)
751 //
752 usleep(100000); // 0.1s
753
754 //
755 // get position, where we are
756 //
757 old = ist;
758 ist = GetSePos(); // [se]
759
760 //
761 // if the position didn't change continue
762 //
763 if ((int)ist.Zd() == (int)old.Zd() &&
764 (int)ist.Az() == (int)old.Az())
765 continue;
766
767 istre = GetRePosPdo();
768
769 //
770 // Get time from last shaftencoder position change (position: ist)
771 // FIXME: I cannot take the avarage
772 //
773 time.Zd((fAlt1->GetMjd()+fAlt2->GetMjd())/2.0);
774 time.Az(fAz->GetMjd());
775
776 //
777 // if Shaftencoder changed position
778 // calculate were we should be
779 //
780 if ((int)ist.Zd() != (int)old.Zd())
781 {
782 sla.SetMjd(time.Zd());
783 sollzd = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
784 }
785
786 if ((int)ist.Az() != (int)old.Az())
787 {
788 sla.SetMjd(time.Az());
789 sollaz = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
790 }
791
792 fTrackingError.Set((ist.Zd()-sollzd.Zd())*kGearRatio.X(),
793 (ist.Az()-sollaz.Az())*kGearRatio.Y());
794
795 fout << setprecision(15) << setw(15) << time.Zd()*60.*60.*24. << " ";
796 fout << setprecision(5) << setw(5) << fTrackingError.Zd() << " ";
797 fout << setprecision(15) << setw(15) << time.Az()*60.*60.*24. << " ";
798 fout << setprecision(5) << setw(5) << fTrackingError.Az() << endl;
799 }
800
801 fout << endl << endl;
802 }
803}
804
805Bool_t MCosy::HandleTimer(TTimer *t)
806{
807 //
808 // Update Gui, foremer MTGui.
809 //
810 fAlt1->DisplayVal();
811 fAlt2->DisplayVal();
812 fAz->DisplayVal();
813
814 ZdAz ist = GetSePos()*(360.0/16384.0); // [se]
815
816 fWin->Update(ist, fTrackingError/kGearRatio2,
817 fVelocity, fOffset/*/kGearRatio2*/,
818 fStatus);
819
820 return kTRUE;
821}
822
823
824int MCosy::StopWaitingForSDO() const
825{
826 return Break() || HasError();
827}
828
829void MCosy::Start()
830{
831 // Don't call this function twice!
832 Network::Start();
833
834 lout << "- Starting TX Thread." << endl;
835 fTTalk = new MTTalk(this);
836
837 lout << "- Starting GUI update." << endl;
838 fUpdateGui->TurnOn();
839 // fTGui = new MTGui(this);
840}
841
842void MCosy::Stop()
843{
844
845 lout << "- Stopping GUI update." << endl;
846 fUpdateGui->TurnOff();
847 lout << "- GUI Update stopped." << endl;
848
849 delete fTTalk;
850 lout << "- TX Thread stopped." << endl;
851
852 Network::Stop();
853}
854
855MCosy::MCosy(const char *dev, const int baud, MLog &out)
856: Network(dev, baud, out), fTracking(kFALSE)
857{
858 //
859 // Create Nodes
860 //
861 fMac1=new Macs(1, lout);
862 fMac2=new Macs(2, lout);
863 fMac3=new Macs(3, lout);
864 fAlt1=new ShaftEncoder(4, lout);
865 fAlt2=new ShaftEncoder(5, lout);
866 fAz =new ShaftEncoder(6, lout);
867
868 //
869 // Connect the devices to the network
870 //
871 SetNode(fMac1);
872 SetNode(fMac2);
873 SetNode(fMac3);
874 SetNode(fAlt1);
875 SetNode(fAlt2);
876 SetNode(fAz);
877
878 //
879 // Create Gui Event timer and Gui
880 //
881 fUpdateGui = new TTimer(this, 100); // 100ms
882
883 fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
884
885 fAz->SetDisplay(fWin->GetLabel1());
886 fAlt1->SetDisplay(fWin->GetLabel2());
887 fAlt2->SetDisplay(fWin->GetLabel3());
888
889 lout.SetOutputGui(fWin->GetLog(), kTRUE);
890}
891
892void MCosy::TerminateApp()
893{
894 cout << "MCosy::TerminateApp()" << endl;
895/*
896 Int_t rc;
897 TGMessageBox msg(this, gClient->GetRoot(),
898 "Information",
899 "Cosy is shutting down the system - this may take wa while!",
900 kMBIconExclamation,
901 kMBOK, //kMBClose
902 &rc, 0);
903*/
904
905 gApplication->Terminate(0);
906}
907
908MCosy::~MCosy()
909{
910 cout << "Deleting GUI timer." << endl;
911
912 delete fUpdateGui;
913
914 cout << "Deleting Nodes." << endl;
915
916 delete fAz;
917 delete fAlt2;
918 delete fAlt1;
919 delete fMac1;
920 delete fMac2;
921 delete fMac3;
922
923 cout << "Deleting MGCosy." << endl;
924
925 lout.DisableOutputDevice(MLog::eGui);
926
927 delete fWin;
928
929 cout << "MGCosy destructed." << endl;
930}
Note: See TracBrowser for help on using the repository browser.