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

Last change on this file since 1061 was 926, checked in by tbretz, 24 years ago
*** empty log message ***
File size: 23.3 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 = fZd1->GetPos();
128 const int p1 = fZd2->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 {
365 lout << "Warning: Azimuth speed limit exceeded. Limiting speed to 90% max." << endl;
366 vt->Az(0.9*vraz*sgn(vt->Az()));
367 }
368
369 if (sgn(vt->Zd()) != sgn(vcalc.Zd()) &&
370 fabs(vt->Zd()) < limit*fabs(vcalc.Zd()))
371 vt->Zd(0);
372 else
373 if (fabs(vt->Zd()) > 0.9*vrzd)
374 {
375 lout << "Warning: Altitude speed limit exceeded. Limiting speed to 90% max." << endl;
376 vt->Zd(0.9*vrzd*sgn(vt->Zd()));
377 }
378}
379
380void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
381{
382 SlaStars sla;
383
384 //
385 // Position to actual position
386 //
387 sla.SetMjd2Now();
388 ZdAz dest = sla.CalcZdAz(dst);
389
390 if (!SetPosition(dest))
391 {
392 lout << "Error: Cannot start tracking, positioning failed." << endl;
393 return;
394 }
395
396 //
397 // calculate offset from present se position
398 //
399 const ZdAz sepos = GetSePos()*kGearRatio;
400
401 if (!RequestRePos())
402 return;
403
404 //
405 // Estimate Offset before starting to track
406 //
407 fOffset = sepos-GetRePos();
408
409 /*
410 cout << "Sepos: " << sepos.Zd() << "re, " << sepos.Az() << "re" << endl;
411 cout << "Repos: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
412 cout << "Offset: " << fOffset.Zd() << "re, " << fOffset.Az() << "re" << endl;
413 */
414
415 //
416 // Init accelerations and Rpm Mode
417 //
418 InitTracking();
419
420 lout << "Start tracking:";
421 lout << " Ra: " << Rad2Deg(dst.Ra()) << "\xb0 ";
422 lout << "Dec: " << Rad2Deg(dst.Dec()) << "\xb0" << endl;
423
424 //
425 // Initialize Tracker (slalib or starguider)
426 //
427 fRaDec = dst;
428 fTracking = kTRUE;
429
430 ofstream fout("log/cosy.pos");
431 fout << "Tracking:";
432 fout << " Ra: " << Rad2Deg(dst.Ra()) << "\x9c ";
433 fout << "Dec: " << Rad2Deg(dst.Dec()) << "\x9c" << endl << endl;
434 fout << " Mjd/10ms V/re/min/4" << endl;
435
436 //
437 // We want to reach the theoretical position exactly in about 0.5s
438 //
439 const float dt = 1; // 1 second
440 while (!StopWaitingForSDO())
441 {
442 //
443 // Request Target position for this moment
444 //
445 sla.Now();
446
447 //
448 // Request theoretical Position for a time in the future (To+dt) from CPU
449 //
450 sla.SetMjd(sla.CalcMjd()+dt/(60*60*24));
451 dest = CorrectTarget(GetSePos(), sla.CalcZdAz(dst)); // [se]
452
453 ZdAz vcalc = sla.GetApproxVel(dst) * kGearRatio2*4./60.; // [re/min]
454
455 //
456 // Request absolute position of rotary encoder from Macs
457 //
458 if (!RequestRePos())
459 break;
460
461 //
462 // distance between (To+dt) and To [re]
463 // position time difference < 5usec
464 // fOffset does the synchronization between the
465 // Shaft- and the rotary encoders
466 //
467 dest *= kGearRatio; // [re]
468 dest -= GetRePos() + fOffset;
469
470 //
471 // Velocity to go [re/min] to reach the right position at time t+dt
472 // correct for the duration of RaDec2AltAz
473 //
474 const ZdAz v = dest*60.0/(dt-(fMac2->GetTime()-sla));
475
476 //
477 // calculate real velocity of future [re/min]
478 // believing the Macs manual '/4' shouldn't be necessary, but it is.
479 //
480 ZdAz vt = v/4;
481 LimitSpeed(&vt, vcalc);
482 vt.Round();
483
484 //
485 // check if the drive is fast enough to follow the star
486 //
487 if (vt.Zd()>.9*fMac1->GetVelRes() || vt.Az()>.9*fMac2->GetVelRes())
488 {
489 lout << "Error: Tracking speed faster than 90% of possible maximum velocity." << endl;
490 break;
491 }
492
493 //
494 // Set theoretical velocity (as early after calculation as possible)
495 // Maybe we should attenuate the changes
496 //
497 if (!SetVelocity(vt))
498 break;
499
500 //
501 // Now do 'unnecessary' things
502 //
503 fVelocity = vt/kGearRatio2*4;
504
505 const double mjd = fMac2->GetMjd();
506 fout << setprecision(15) << setw(17) << mjd*60.*60.*24. << " ";
507 fout << setw(4) << vt.Zd() << " ";
508 fout << setw(4) << vt.Az() << endl;
509 //
510 // FIXME? Calculate an accuracy for the tracking system?
511 // How good do we reach the calculated position in 'real'
512 // re valus?
513 //
514
515
516 //
517 // Update speed as often as possible.
518 // make sure, that dt is around 10 times larger than the
519 // update time
520 //
521 // usleep(50000); // 0.05s
522 }
523
524 fTracking = kFALSE;
525 StopMovement();
526 lout << "Tracking stopped." << endl;
527}
528
529int MCosy::IsPositioning() const
530{
531 return (fMac1->IsPositioning() || fMac2->IsPositioning()) && !StopWaitingForSDO();
532}
533
534void MCosy::WaitForEndMovement()
535{
536 WaitForSdos();
537
538 while (IsPositioning())
539 usleep(1);
540}
541
542void MCosy::StopMovement()
543{
544 SetStatus(kStopping);
545
546 cout << "Stopping positioning..." << endl;
547 fMac1->SetDeceleration(0.5*fMac1->GetVelRes());
548 fMac2->SetDeceleration(0.5*fMac2->GetVelRes());
549
550 cout << "Stoping possible RPM mode..." << endl;
551 fMac1->SetRpmMode(FALSE);
552 fMac2->SetRpmMode(FALSE);
553
554 cout << "Waiting for silence..." << endl;
555 WaitForEndMovement();
556
557 CheckForError();
558
559 cout << "Movement stopped." << endl;
560}
561
562void *MCosy::Proc(int msg, void *mp)
563{
564 switch (msg)
565 {
566 case WM_WAIT:
567 cout << "Wait for execution of Proc(WM_*, ): done." << endl;
568 return NULL;
569
570 case WM_STOP:
571 StopMovement();
572 return NULL;
573
574 case WM_PRESET:
575 cout << "WM_Preset: start." << endl;
576 fZd1->SetPreset();
577 fZd2->SetPreset();
578 fAz->SetPreset();
579 cout << "WM_Preset: done. (return 0xaffe)" << endl;
580 return (void*)0xaffe;
581
582 case WM_POLARIS:
583 {
584 cout << "WM_Polaris: start." << endl;
585 SlaStars sla;
586 sla.SetMjd2Now();
587
588 RaDec rd(37.94, 89.2644);
589 ZdAz za=sla.CalcZdAz(rd*D2PI/360.0)*16384.0/D2PI;
590
591 cout << "Calc Zd: " << za.Zd() << " Az: " << za.Az() << endl;
592
593 ZdAz sepos = GetSePos();
594 cout << "Got Zd: " << sepos.Zd() << " Az: " << sepos.Az() << endl;
595
596 fZd1->SetPreset(za.Zd());
597 fZd2->SetPreset(-za.Zd());
598 fAz->SetPreset(za.Az());
599
600 cout << "WM_Polaris: done. (return 0xaffe)" << endl;
601 }
602 return (void*)0xaffe;
603
604 case WM_POSITION:
605 cout << "WM_Position: start." << endl;
606 {
607 ZdAz dest = *((ZdAz*)mp);
608
609 SetPosition(dest*D2PI/360.0);
610 }
611 cout << "WM_Position: done. (return 0x7777)" << endl;
612 return (void*)0x7777;
613
614 case WM_TRACK:
615 cout << "WM_Track: START" << endl;
616 {
617 RaDec dest = *((RaDec*)mp);
618 TrackPosition(dest*D2PI/360.0);
619 }
620 cout << "WM_Track: done. (return 0x8888)" << endl;
621 return (void*)0x8888;
622
623 case WM_QUIT:
624 cout << "WM_Quit: now." << endl;
625 TerminateApp();
626 cout << "WM_Quit: done." << endl;
627 return (void*)0x9999;
628 }
629 cout << "Unknown Msg" << endl;
630 return (void*)0xffffffff;
631}
632
633void *MTTalk::Thread()
634{
635 fCosy->TalkThread();
636 return NULL;
637}
638
639void MCosy::TalkThread()
640{
641 //
642 // Start the Network
643 //
644 cout << "Reading configuration file..." << flush;
645 TEnv env(".cosyrc");
646 cout << "done." << endl;
647
648 const int res = fMac3->GetVelRes();
649
650 fMac3->SetVelocity(res);
651 fMac3->SetAcceleration(res);
652 fMac3->SetDeceleration(res);
653
654 fMac3->StartPosSync();
655
656 cout << "Going Home..." << endl;
657 fMac1->SetHome(250000, env.GetValue("Az_MaxTime2ReachHome[s]", 100));
658 fMac2->SetHome(250000, env.GetValue("Zd_MaxTime2ReachHome[s]", 100));
659 PostMsg(WM_PRESET, 0, 0);
660 PostMsg(WM_WAIT, 0, 0);
661
662 fMac1->ReqPos();
663 fMac2->ReqPos();
664
665 //const ZdAz repos=GetRePos();
666 //cout << "APOS: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
667
668 /*
669 cout << Deg2AzRE(env.GetValue("MinAz[Deg]", -1.0)) << " < Az < "
670 << Deg2AzRE(env.GetValue("MaxAz[Deg]", +1.0)) << "RE" << endl;
671 cout << env.GetValue("MinAz[Deg]", -1.0) << " < Az < "
672 << env.GetValue("MaxAz[Deg]", +1.0) << kDEG << endl;
673 cout << Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)) << "RE < Zd < "
674 << Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)) << "RE" << endl;
675 */
676
677 cout << "Setting up software endswitch..." << flush;
678 fMac1->SetNegEndswitch(Deg2AzRE(env.GetValue("Az_Min[Deg]", -1.0)));
679 fMac1->SetPosEndswitch(Deg2AzRE(env.GetValue("Az_Max[Deg]", +1.0)));
680
681 fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("Zd_Min[Deg]", -1.0)));
682 fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("Zd_Max[Deg]", +1.0)));
683 cout << "done." << endl;
684
685 fMac1->EnableTimeout(kTRUE, 500);
686 fMac2->EnableTimeout(kTRUE, 500);
687
688/*
689 fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)));
690 fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)));
691*/
692// fMac3->StartVelSync();
693/*
694 cout << "PostMsg(WM_PRESET)" << endl;
695 void *rc =
696 cout << hex << "WM_PRESET: ret=" << rc << endl;
697
698 RaDec dest = RaDec(45.0, 30.0)*D2PI/360.0;
699
700 cout << "PostMsg(WM_TRACK)" << endl;
701 cout << sizeof(RaDec) << "==" << sizeof(dest) << endl;
702 rc=PostMsg(WM_TRACK, &dest, sizeof(dest));
703 cout << "DEST killed." << endl;
704*/
705 // AltAz dest = AltAz(45.0, 30.0);
706 // double ra, dec;
707 // slaDaf2r( 71, 0, 0, &ra, &status); // 0 WARNING: RANGE
708 // slaDaf2r( 89, 0, 0, &dec, &status); // 49
709 // cout << "Start tracking: Ra: " << Rad2Deg(ra) << kDEG << " Dec: " << Rad2Deg(dec) << kDEG << endl;
710
711 // dest = AltAz(-46.0, 210);
712 // SetPosition(dest);
713
714 SlaStars sla;
715 while (1)
716 {
717 //
718 // wait until a tracking session is started
719 //
720 while (!fTracking && !fTTalk->HasStopFlag())
721 usleep(1);
722
723 if (fTTalk->HasStopFlag())
724 break;
725
726 ofstream fout("log/cosy.err");
727 fout << "Tracking:";
728 fout << " Ra: " << Rad2Deg(fRaDec.Ra()) << "\x9c ";
729 fout << "Dec: " << Rad2Deg(fRaDec.Dec()) << "\x9c" << endl << endl;
730 fout << " MjdZd/10ms ErrZd/re";
731 fout << " MjdAz/10ms ErrAd/re" << endl;
732
733 ZdAz old;
734 ZdAz ist;
735
736 ZdAz sollzd;
737 ZdAz sollaz;
738
739 ZdAz istre = -fOffset; // [re]
740 ZdAz time;
741
742 //
743 // only update fTrackingError while tracking
744 //
745 while (fTracking && !fTTalk->HasStopFlag())
746 {
747 //
748 // Make changes (eg wind) smoother - attenuation of control function
749 //
750 const float weight = 1.; //0.3;
751
752 ZdAz offset(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight,
753 fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight);
754
755 fOffset = offset;
756
757 //
758 // This is the time constant which defines how fast
759 // you correct for external influences (like wind)
760 //
761 bool phca1;
762 bool phca2;
763 bool phcaz;
764
765 do
766 {
767 phca1 = fZd1->PosHasChanged();
768 phca2 = fZd2->PosHasChanged();
769 phcaz = fAz->PosHasChanged();
770 usleep(1);
771 } while (!phca1 && !phca2 && !phcaz);
772 //---usleep(100000); // 0.1s
773
774 //
775 // get position, where we are
776 //
777 old = ist;
778 ist = GetSePos(); // [se]
779
780 //
781 // if the position didn't change continue
782 //
783 /*---
784 if ((int)ist.Zd() == (int)old.Zd() &&
785 (int)ist.Az() == (int)old.Az())
786 continue;
787 */
788 istre = GetRePosPdo();
789
790 //
791 // Get time from last shaftencoder position change (position: ist)
792 // FIXME: I cannot take the avarage
793 //
794 time.Zd((fZd1->GetMjd()+fZd2->GetMjd())/2.0);
795 time.Az(fAz->GetMjd());
796
797 //
798 // if Shaftencoder changed position
799 // calculate were we should be
800 //
801 if (phca1 || phca2 /*(int)ist.Zd() != (int)old.Zd()*/)
802 {
803 sla.SetMjd(time.Zd());
804 sollzd = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
805 }
806
807 if (phcaz /*(int)ist.Az() != (int)old.Az()*/)
808 {
809 sla.SetMjd(time.Az());
810 sollaz = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
811 }
812
813 fTrackingError.Set((ist.Zd()-sollzd.Zd())*kGearRatio.X(),
814 (ist.Az()-sollaz.Az())*kGearRatio.Y());
815
816 fout << setprecision(15) << setw(17) << time.Zd()*60.*60.*24. << " ";
817 fout << setprecision(5) << setw(7) << fTrackingError.Zd() << " ";
818 fout << setprecision(15) << setw(17) << time.Az()*60.*60.*24. << " ";
819 fout << setprecision(5) << setw(7) << fTrackingError.Az() << endl;
820 }
821
822 fout << endl << endl;
823 }
824}
825
826Bool_t MCosy::HandleTimer(TTimer *t)
827{
828 //
829 // Update Gui, foremer MTGui.
830 //
831 fZd1->DisplayVal();
832 fZd2->DisplayVal();
833 fAz->DisplayVal();
834
835 ZdAz ist = GetSePos()*(360.0/16384.0); // [se]
836
837 fWin->Update(ist, fTrackingError/kGearRatio2,
838 fVelocity, fOffset/*/kGearRatio2*/,
839 fStatus);
840
841 return kTRUE;
842}
843
844
845int MCosy::StopWaitingForSDO() const
846{
847 return Break() || HasError();
848}
849
850void MCosy::Start()
851{
852 // Don't call this function twice!
853 Network::Start();
854
855 lout << "- Starting TX Thread." << endl;
856 fTTalk = new MTTalk(this);
857
858 lout << "- Starting GUI update." << endl;
859 fUpdateGui->TurnOn();
860 // fTGui = new MTGui(this);
861}
862
863void MCosy::Stop()
864{
865
866 lout << "- Stopping GUI update." << endl;
867 fUpdateGui->TurnOff();
868 lout << "- GUI Update stopped." << endl;
869
870 delete fTTalk;
871 lout << "- TX Thread stopped." << endl;
872
873 Network::Stop();
874}
875
876MCosy::MCosy(const char *dev, const int baud, MLog &out)
877: Network(dev, baud, out), fTracking(kFALSE)
878{
879 //
880 // Create Nodes
881 //
882 fMac1=new Macs(1, "Mac.1/Az", lout);
883 fMac2=new Macs(2, "Mac.2/Zd", lout);
884 fMac3=new Macs(3, "Mac.3/Az-Sync", lout);
885
886 fZd1=new ShaftEncoder(4, "SE.4/Zd1", lout);
887 fZd2=new ShaftEncoder(5, "SE.5/Zd2", lout);
888 fAz =new ShaftEncoder(6, "SE.6/Az", lout);
889
890 //
891 // Connect the devices to the network
892 //
893 SetNode(fMac1);
894 SetNode(fMac2);
895 SetNode(fMac3);
896 SetNode(fZd1);
897 SetNode(fZd2);
898 SetNode(fAz);
899
900 //
901 // Create Gui Event timer and Gui
902 //
903 fUpdateGui = new TTimer(this, 100); // 100ms
904
905 fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
906
907 fAz->SetDisplay(fWin->GetLabel1());
908 fZd1->SetDisplay(fWin->GetLabel2());
909 fZd2->SetDisplay(fWin->GetLabel3());
910
911 lout.SetOutputGui(fWin->GetLog(), kTRUE);
912}
913
914void MCosy::TerminateApp()
915{
916 cout << "MCosy::TerminateApp()" << endl;
917/*
918 Int_t rc;
919 TGMessageBox msg(this, gClient->GetRoot(),
920 "Information",
921 "Cosy is shutting down the system - this may take wa while!",
922 kMBIconExclamation,
923 kMBOK, //kMBClose
924 &rc, 0);
925*/
926
927 gApplication->Terminate(0);
928}
929
930MCosy::~MCosy()
931{
932 cout << "Deleting GUI timer." << endl;
933
934 delete fUpdateGui;
935
936 cout << "Deleting Nodes." << endl;
937
938 delete fAz;
939 delete fZd2;
940 delete fZd1;
941 delete fMac1;
942 delete fMac2;
943 delete fMac3;
944
945 cout << "Deleting MGCosy." << endl;
946
947 lout.DisableOutputDevice(MLog::eGui);
948
949 delete fWin;
950
951 cout << "MGCosy destructed." << endl;
952}
Note: See TracBrowser for help on using the repository browser.