source: trunk/MagicSoft/Cosy/main/MPointing.cc@ 4103

Last change on this file since 4103 was 4076, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 7.6 KB
Line 
1#include "MPointing.h"
2
3#include "MCosy.h"
4#include "macs.h"
5#include "MDriveCom.h"
6
7ClassImp(MPointing);
8
9//#define EXPERT
10#undef EXPERT
11
12// --------------------------------------------------------------------------
13//
14// set the velocity and accelerations for position maneuvers.
15//
16// The acceleratin is set as given (in percent of maximum).
17// The velocity is given in percent, depending on the ratio (<1 or >1)
18// one of the axis becomes a slower velocity. This is used for maneuvers
19// in which both axis are moved synchromously and should reach their
20// target position at the same time.
21//
22void MPointing::SetPosVelocity(const Float_t ratio, Float_t vel)
23{
24 //
25 // Set velocities
26 //
27 const int vr = fCosy->fMac1->GetVelRes();
28 vel *= vr;
29
30 if (ratio<1)
31 {
32 fCosy->fMac1->SetVelocity(vel);
33 fCosy->fMac2->SetVelocity(vel*ratio);
34 }
35 else
36 {
37 fCosy->fMac1->SetVelocity(vel/ratio);
38 fCosy->fMac2->SetVelocity(vel);
39 }
40}
41
42// --------------------------------------------------------------------------
43//
44// Does a relative positioning.
45//
46// The steps to move are given in a ZdAz object relative to the current
47// position. The coordinates are given in Roteryencoder steps.
48// Axis 1 is moved only if axe1==kTRUE, Axis 2 is moved only
49// if Axis 2==kTRUE. The function waits for the movement to be finished.
50//
51void MPointing::DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2)
52{
53 if (fCosy->HasZombie())
54 return;
55
56 fCosy->SetStatus(MDriveCom::kMoving);
57
58 if (axe1) fCosy->fMac2->StartRelPos(rd.Zd());
59 if (axe2) fCosy->fMac1->StartRelPos(rd.Az());
60#ifdef EXPERT
61 cout << "Waiting for positioning..." << flush;
62#endif
63 if (axe1) fCosy->fMac2->WaitForSdo(0x6004, 1);
64 if (axe2) fCosy->fMac1->WaitForSdo(0x6004, 1);
65
66 fCosy->WaitForEndMovement();
67#ifdef EXPERT
68 cout << "done." << endl;
69#endif
70}
71
72bool MPointing::SetAccDec(Macs *mac, Float_t acc, Float_t dec)
73{
74 const int vr = mac->GetVelRes();
75 mac->SetAcceleration(acc*vr);
76 mac->SetDeceleration(dec*vr);
77 return !mac->IsZombieNode();
78}
79
80bool MPointing::Break()
81{
82 return fCosy->Break() || fCosy->HasError() || fCosy->HasZombie();
83}
84
85// --------------------------------------------------------------------------
86//
87// Move the telescope to the given position. The position must be given in
88// a ZdAz object in rad.
89//
90// The first positioning is done absolutely. If we didn't reach the
91// correct psotion we try to correct for this by 10 relative position
92// maneuvers. If this doesn't help positioning failed.
93//
94// As a reference the shaftencoder values are used.
95//
96int MPointing::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
97{
98 const ZdAz d = dst*kRad2Deg;
99
100 MTime t(-1);
101 lout << t << " - Target Position: " << d.Zd() << "deg, " << d.Az() << "deg (Zd/Az)" << endl;
102
103 //
104 // Calculate new target position (shortest distance to go)
105 //
106 //const ZdAz src = fCosy->GetSePos(); // [se]
107
108 //
109 // Make sure that the motors are in sync mode (necessary if the
110 // MACS has been rebooted from a Zombie state.
111 //
112 //InitSync();
113 //if (fMac3->IsZombieNode())
114 // return false;
115
116 //
117 // Because we agreed on I don't search for the shortest move
118 // anymore
119 //
120 // const ZdAz dest = CorrectTarget(src, dst);
121 //
122 ZdAz bend = fCosy->fBending(dst); // [rad]
123
124 const ZdAz dest = bend*fCosy->kResSE/TMath::TwoPi(); // [se]
125
126 if (!fCosy->CheckRange(bend))
127 return kFALSE;
128
129 bend *= kRad2Deg;
130 fCosy->fZdAzSoll = dst;
131
132 //cout << "Source Zd: " << src.Zd() << "se Az:" << src.Az() << "se" << endl;
133 //cout << "Destination Zd: " << Rad2SE(dst.Zd()) << "se Az:" << Rad2SE(dst.Az()) << "se" << endl;
134 //cout << "Bend'd Dest Zd: " << dest.Zd() << "se Az:" << dest.Az() << "se" << endl;
135 //cout << "Bend'd Dest Zd: " << bend.Zd() << "deg Az:" << bend.Az() << "deg" << endl;
136
137 //
138 // Set velocities
139 //
140 //const int vr = fCosy->fMac1->GetVelRes();
141
142 const Float_t rad2se = fCosy->kResSE.X()/TMath::TwoPi();
143
144 int i;
145 for (i=0; i<(track?1:10) && !Break()/*(fCosy->Break() || fCosy->HasError() || fCosy->HasZombie())*/; i++)
146 {
147
148 lout << "- Step #" << i << endl;
149
150 // Get Shaft Encoder Positions
151 const ZdAz p=fCosy->GetSePos();
152
153 // calculate control deviation and rounded cd
154 ZdAz rd = dest-p; // [se]
155 ZdAz cd = rd; // [se]
156 cd.Round();
157
158 // Check if there is a control deviation on the axis
159 const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
160 const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
161
162 // check if we reached the correct position already
163 if (!cdzd && !cdaz)
164 {
165 t.Now();
166 lout << t << " - Positioning done in " << i << (i==1?" step.":" steps.") << endl;
167 fCosy->SetStatus(MDriveCom::kStopped);
168 fCosy->fCom->SendStatus("Target position reached.");
169 return TRUE;
170 }
171
172 // ==============================================
173 // Estimate the noncircularity of the zd axis
174 const ZdAz ist = dst-rd*TMath::TwoPi()/fCosy->kResSE;
175
176 const double p1 = ist.Zd()-19.0605/kRad2Deg;
177 const double p2 = dst.Zd()-19.0605/kRad2Deg;
178
179 const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*rad2se;
180 const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*rad2se;
181 // ==++=========================================
182
183 // change units from se to re
184 rd *= fCosy->kGearTot/fCosy->kResSE; // [re]
185 rd.Zd(f2-f1);
186
187 // Initialize Velocities so that we reach both positions
188 // at the same time
189 if (i)
190 {
191 //lout << "--- LO-SPEED ---" << endl;
192 SetAccDec(fCosy->fMac1, 0.1, 0.1);
193 SetAccDec(fCosy->fMac2, 0.1, 0.1);
194
195 SetPosVelocity(1.0, 0.05);
196 }
197 else
198 {
199 const Double_t y = 15*fCosy->kGearTot.Y()*fCosy->kResSE.Y();
200 if (rd.Az()>-y && rd.Az()<y)
201 {
202 //lout << "--- LO-SPEED Mac1 ---" << endl;
203 SetAccDec(fCosy->fMac1, 0.05, 0.05);
204 }
205 else
206 SetAccDec(fCosy->fMac1, fAcc, fDec);
207
208 SetAccDec(fCosy->fMac2, fAcc, fDec);
209
210 SetPosVelocity(fabs(rd.Ratio()), fVel);
211 }
212
213 rd.Round();
214
215 // FIXME? Check for Error or Zombie?
216
217 // cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
218 // cout << " + APOS: Zd=" << setw(6) << p.Zd() << "se Az=" << setw(6) << p.Az() << "se" << endl;
219 // cout << " + dZd=" << setw(6) << cd.Zd() << "se dAz=" << setw(6) << cd.Az() << "se" << endl;
220 // cout << " + dZd=" << setw(6) << rd.Zd() << "re dAz=" << setw(6) << rd.Az() << "re" << endl;
221 // cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X() << "se Az=" << setw(6) << kGearRatio.Y() << "se" << endl;
222
223 // repositioning (relative)
224 lout << "- Do Relative Positioning..." << endl;
225 DoRelPos(rd, cdzd, cdaz);
226 lout << "- Relative Positioning Done" << endl;
227 }
228 if (i==1 && track && !Break()/*(fCosy->Break() || fCosy->HasError() || fCosy->HasZombie())*/)
229 {
230 t.Now();
231 lout << t << " - Positioning done." << endl;
232 fCosy->SetStatus(MDriveCom::kStopped);
233 fCosy->fCom->SendStatus("Tracking preposition reached.");
234 return TRUE;
235 }
236
237 if (i<10)
238 fCosy->StopMovement();
239 else
240 fCosy->SetStatus(MDriveCom::kStopped);
241
242 t.Now();
243 lout << t << " - Warning: Requested position not reached (i=" << dec << i << ")" << endl;
244
245 fCosy->fCom->SendStatus("Target position missed!");
246
247 return FALSE;
248}
Note: See TracBrowser for help on using the repository browser.