source: trunk/MagicSoft/Cosy/main/MSlewing.cc@ 8875

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