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

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