Index: trunk/MagicSoft/Cosy/Changelog
===================================================================
--- trunk/MagicSoft/Cosy/Changelog	(revision 7229)
+++ trunk/MagicSoft/Cosy/Changelog	(revision 7230)
@@ -1,3 +1,28 @@
                                                                   -*-*- END -*-*-
+
+ 2005/07/28 - Florian Goebel
+
+  * videodev/FilterLed.[cc,h]
+    - add GetMeanPositionCircle and FindStarCircle
+ 
+  * devdrv/shaftencoder.[cc,h]
+    - add: fDirHasChanged, fDirChangedPos, fDirChangedOffset,
+           fDirection, fHysteresisPos, fHysteresisNeg
+
+  * main/MCosy.cc
+    - set faster acceleration and Velocity parameters in TrackPositionGRB
+
+  * main/MPointing.cc
+    - correct bug which always set speed to LO-SPEED
+
+  * main/MStarguider.[cc,h]
+    - add new Popup "Operation" (functionality is not ready yet)
+    - add new procedure: FindRoqueLamp
+    - in MStarguider::FindStar now use Leds::FindStarCircle 
+      (instead of Leds::FindStar)
+
+  * main/MTracking.cc
+    - calculate DirHasChanged etc.
+ 
 
  2005/04/11 - Thomas Bretz
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 7229)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 7230)
@@ -16,6 +16,9 @@
 ShaftEncoder::ShaftEncoder(const BYTE_t nodeid, const char *name, MLog &out)
     : NodeDrv(nodeid, name, out), fPos(0), fVel(0), fAcc(0),
-    fTurn(0), fLabel(NULL), fPosHasChanged(false), fReport(NULL),/*fTwin(0),
-    fIsUpdated(kFALSE),*/ fMotor(0), fOffset(0)
+    fTurn(0), fLabel(NULL), fPosHasChanged(false), fDirHasChanged(false),
+    fReport(NULL),
+    /*fTwin(0), fIsUpdated(kFALSE),*/
+      fMotor(0), fOffset(0), fDirChangedPos(0),
+      fDirection(kUndefined), fHysteresisPos(0), fHysteresisNeg(0)
 {
 }
@@ -93,5 +96,9 @@
         fPos  = val;
         fTurn = 0;
+        fDirChangedPos = val;
         fOffset = fMotor ? fMotor->GetPdoPos() : 0;
+        fPosHasChanged = true;
+        fDirHasChanged = true;
+	fDirection = kUndefined;
         //fIsUpdated=kTRUE;
         //fOffset = 0;
@@ -198,6 +205,15 @@
     //    return;
 
+    // Warning: A multiturn shaftencoder is assumed!
+    if ((pos>fDirChangedPos && pos<fPos) ||
+        (pos<fDirChangedPos && pos>fPos))
+    {
+        fDirChangedPos = pos;
+        fDirHasChanged = true;
+    }
+    else
+        fOffset = fMotor ? fMotor->GetPdoPos() : 0;
+
     fPos = pos;
-    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
     fTime.Set(*tv);
     fPosHasChanged = true;
@@ -225,7 +241,16 @@
     //    return;
 
+    // Warning: A multiturn shaftencoder is assumed!
+    if ((pos>fDirChangedPos && pos<fPos) ||
+        (pos<fDirChangedPos && pos>fPos))
+    {
+        fDirChangedPos = pos;
+        fDirHasChanged = true;
+    }
+    else
+        fOffset = fMotor ? fMotor->GetPdoPos() : 0;
+
     //CheckTwin(fPos-pos);
     fPos=pos;
-    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
     fTime.Set(*tv);
     fPosHasChanged=true;
@@ -267,4 +292,6 @@
         turn--;
 
+    LWORDS_t multipos = pos+turn*fTicks; // SE position of multiturn shaftencoder
+
     //if (fPos==pos && fTurn==fTurn)
     //    return;
@@ -272,8 +299,27 @@
     //CheckTwin(fPos-pos);
 
+    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
+
+    // Warning: A multiturn shaftencoder is assumed!
+    if ((multipos>fDirChangedPos && multipos<fPos) ||
+        (multipos<fDirChangedPos && multipos>fPos))
+    {
+        fDirChangedPos = GetPos();
+        fDirHasChanged = true;
+	fDirChangedOffset = fOffset;
+    }
+    else 
+    {
+	fDirHasChanged = false;
+    }
+
+    if (multipos>GetPos()) fDirection = kForward;
+    else if (multipos<GetPos()) fDirection = kBackward;
+    else fDirection = kUndefined;
+
+
     fPos  = pos;
     fTurn = turn;
 
-    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
     fTime.Set(*tv);
     fPosHasChanged=true;
@@ -281,9 +327,9 @@
     //fOffset = 0;
 
-
     if (fReport)
     {
         fReport->Lock("ShaftEncoder::HandlePDOType2");
         *fReport << "SE-REPORT " << (int)GetId() << " " << fTime << " PDO2 " << pos << " " << fVel << " " << fAcc << " " << GetNodeName() << endl;
+	*fReport << "DIR-REPORT " << (int)GetId() << " " << (Int_t)fDirHasChanged << " " << (Int_t)fDirChangedPos << endl;
         fReport->UnLock("ShaftEncoder::HandlePDOType2");
     }
@@ -415,6 +461,11 @@
     fPos  = pre%16384;
     fTurn = pre/16384;
-
+    fDirChangedPos = fPos;
     fOffset = fMotor ? fMotor->GetPdoPos() : 0;
+
+    fPosHasChanged = true;
+    fDirHasChanged = true;
+
+    fDirection = kUndefined;
 }
 
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 7229)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 7230)
@@ -13,4 +13,6 @@
 class TGLabel;
 
+enum Direction_t { kUndefined, kForward, kBackward };                                                    
+
 class ShaftEncoder : public NodeDrv
 {
@@ -23,14 +25,23 @@
     WORD_t   fTurns; // Number of possible turns
 
+    Direction_t fDirection;
+  
+    Float_t fHysteresisPos;
+    Float_t fHysteresisNeg;
+
     TGLabel  *fLabel;     //
     LWORDS_t  fUpdPos;    // ticks
 
     bool fPosHasChanged;  //!
+    bool fDirHasChanged;  //!
 
     MTime fTime;
     MLog *fReport;
 
-    Macs *fMotor;
-    Int_t fOffset;
+    Macs *fMotor;     // Corresponding Motor/MACS
+    Int_t fOffset;    // offset between SE and Motor
+    Int_t fDirChangedPos; // Last position at which the SE changed its moving direction
+    Int_t fDirChangedOffset; // Offset between SE and Motor when SE changed its moving direction last
+
 
     void HandlePDOType0(BYTE_t *data, timeval_t *tv);
@@ -62,7 +73,11 @@
     void HandlePDO2(BYTE_t *data, timeval_t *tv) { HandlePDOType2(data, tv); }
 
-    LWORDS_t GetPos() const { return IsZombieNode() ? 0 : fPos+fTurn*fTicks; } // FIXME? 0?
+    LWORDS_t GetPos() const       { return IsZombieNode() ? 0 : fPos+fTurn*fTicks; } // FIXME? 0?
+    Int_t    GetDirection() const { return IsZombieNode() ? 0 : fPos-fDirChangedPos; } // FIXME? 0?
+    Int_t    GetDirChangedPos() const { return IsZombieNode() ? 0 : fDirChangedPos; } // FIXME? 0?
     LWORD_t  GetPhysRes() const { return fTicks; }
     Int_t    GetOffset() const { return fOffset; }
+    Int_t    GetDirChangedOffset() const { return fDirChangedOffset; }
+
     void     SetOffset(Int_t off) { fOffset = off; }
 
@@ -74,7 +89,23 @@
 
     bool PosHasChanged() const { return fPosHasChanged; }
+    bool DirHasChanged() const { return fDirHasChanged; }
     void ResetPosHasChanged() { fPosHasChanged = false; }
+    void ResetDirHasChanged() { fDirHasChanged = false; }
 
     void SetReport(MLog *log) { fReport = log; }
+
+    void SetHysteresisNeg(Float_t f) { fHysteresisNeg = f; }
+    void SetHysteresisPos(Float_t f) { fHysteresisPos = f; }
+
+    Float_t GetPosCorrected() const { 
+      switch (fDirection) { 
+      case kUndefined: 
+	return GetPos(); 
+      case kForward: 
+	return GetPos()-fHysteresisPos; 
+      case kBackward: 
+	return GetPos()+fHysteresisNeg; 
+      }
+    }
 
     ClassDef(ShaftEncoder, 0)
Index: trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 7229)
+++ trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 7230)
@@ -397,9 +397,25 @@
 //    point.SetVelocity(0.2); // fast: 0.6, slow: 0.2
 //#else
+
+// original settings
+//
     point.SetPointAccDec(0.2, 0.1);
     point.SetPointVelocity(0.1);
+
+
 //#endif
 
+//    point.SetPointAccDec(0.4, 0.4);
+//    point.SetPointVelocity(0.4);
+
+
+// original
     return point.SetPosition(dst, track);
+
+// test
+//    return point.SetPosition(dst, kTRUE);
+
+
+
 }
 
@@ -422,6 +438,15 @@
 //    track.SetPointVelocity(0.2); // fast: 0.6, slow: 0.2
 //#else
+
+
+
     track.SetPointAccDec(0.2, 0.1);
     track.SetPointVelocity(0.1);
+
+    //    track.SetPointAccDec(0.4, 0.4);
+    // track.SetPointVelocity(0.4);
+
+
+
 //#endif
     track.SetTrackAccDec(0.1, 0.1);
@@ -438,6 +463,6 @@
 //    track.SetPointVelocity(0.2); // fast: 0.6, slow: 0.2
 //#else
-    track.SetPointAccDec(0.2, 0.1);
-    track.SetPointVelocity(0.1);
+    track.SetPointAccDec(0.4, 0.4);
+    track.SetPointVelocity(0.3);
 //#endif
     track.SetTrackAccDec(0.1, 0.1);
Index: trunk/MagicSoft/Cosy/main/MPointing.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MPointing.cc	(revision 7229)
+++ trunk/MagicSoft/Cosy/main/MPointing.cc	(revision 7230)
@@ -202,12 +202,26 @@
         else
         {
-            const Double_t y = 15*fCosy->kGearTot.Y()*fCosy->kResSE.Y();
-            if (rd.Az()>-y && rd.Az()<y)
-            {
-                //lout << "--- LO-SPEED Mac1 ---" << endl;
-                SetAccDec(fCosy->fMac1, 0.05, 0.05);
-            }
-            else
-                SetAccDec(fCosy->fMac1, fAcc, fDec);
+            const Double_t y = 15*fCosy->kGearTot.Y()/fCosy->kResSE.Y();
+
+//	    lout << "MPointing::SetPosition y: " << y << " rd.Az(): " << rd.Az() << endl;
+//	    lout << "MPointing::SetPosition fCosy->kGearTot.Y(): " << fCosy->kGearTot.Y() << " fCosy->kResSE.Y(): " << fCosy->kResSE.Y() << endl;
+
+	    if (rd.Az()>-y && rd.Az()<y)
+	      {
+		//lout << "--- LO-SPEED Mac1 ---" << endl;
+		SetAccDec(fCosy->fMac1, 0.05, 0.05);
+	      }
+	    else
+	      {
+
+ 		//lout << "MPointing::SetPosition SetAccDec Mac1: " << fAcc << fDec << endl;
+		
+ 		SetAccDec(fCosy->fMac1, fAcc, fDec);
+		
+	      }
+
+
+	    // new 16.05.05  F.G.
+	    // SetAccDec(fCosy->fMac1, fAcc, fDec);
 
             SetAccDec(fCosy->fMac2, fAcc, fDec);
Index: trunk/MagicSoft/Cosy/main/MStarguider.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MStarguider.cc	(revision 7229)
+++ trunk/MagicSoft/Cosy/main/MStarguider.cc	(revision 7230)
@@ -70,4 +70,5 @@
     IDM_kChannel1,
     IDM_kChannel2,
+    IDM_kChannel3,
     IDM_kContinous,
     IDM_kRate25ps,
@@ -107,5 +108,7 @@
     IDM_kStargCaosFilter,
     IDM_kStargLEDFilter,
-    IDM_kStargFindStar
+    IDM_kStargFindStar,
+    IDM_kTPointAna,
+    IDM_kRoqueLampAna
 
 };
@@ -143,5 +146,10 @@
     fChannel->AddEntry("Starfield Camera", IDM_kChannel1);
     fChannel->AddEntry("TPoint Camera", IDM_kChannel2);
-    fChannel->CheckEntry(channel==0?IDM_kChannel1:IDM_kChannel2);
+    fChannel->AddEntry("Read from File", IDM_kChannel3);
+    if (channel<0) {
+      fChannel->CheckEntry(IDM_kChannel3);
+    } else {
+      fChannel->CheckEntry(channel==0?IDM_kChannel1:IDM_kChannel2);
+    }
     fChannel->Associate(this);
     fList->Add(fChannel);
@@ -170,4 +178,12 @@
     fList->Add(fDisplay);
 
+
+    fOperations = new MGPopupMenu(p);
+    fOperations->AddEntry("TPoint Analysis",     IDM_kTPointAna);
+    fOperations->AddEntry("Roque Lamp Analysis", IDM_kRoqueLampAna);
+    fOperations->Associate(this);
+    fList->Add(fOperations);
+
+
     fFileType = new MGPopupMenu(p);
     fFileType->AddEntry("PP&M", IDM_kPPM);
@@ -281,7 +297,10 @@
 
     fMenu = new MGMenuBar(this, 0, 0, kHorizontalFrame);
-    fMenu->AddPopup("&Display",   fDisplay,         NULL);
-    fMenu->AddPopup("&WritePics", fWritePictures,   NULL);
-    fMenu->AddPopup("&Setup",     fSetup,           NULL);
+    fMenu->AddPopup("&Display",    fDisplay,         NULL);
+    fMenu->AddPopup("&WritePics",  fWritePictures,   NULL);
+    fMenu->AddPopup("&Setup",      fSetup,           NULL);
+
+    fMenu->AddPopup("&Operations", fOperations,      NULL);
+
     fMenu->Resize(fMenu->GetDefaultSize());
     fMenu->BindKeys(this);
@@ -457,5 +476,11 @@
 
 MStarguider::MStarguider(MObservatory::LocationName_t obs, Int_t channel)
-    : TGMainFrame(gClient->GetRoot(), 768, 840), fCosy(NULL), fOutTp(0), fDx((768-kZOOM)/2), fDy((512-kZOOM)/2), fStatus(MDriveCom::kStandby)
+    : TGMainFrame(gClient->GetRoot(), 768, 840), 
+      fCosy(NULL), 
+      fOutTp(0), 
+      fOutRq(0),
+      fDx((768-kZOOM)/2), 
+      fDy((512-kZOOM)/2), 
+      fStatus(MDriveCom::kStandby)
 {
     
@@ -517,4 +542,7 @@
     if (fOutTp)
         delete fOutTp;
+
+    if (fOutRq)
+        delete fOutRq;
 
     cout << "Camera Display destroyed." << endl;
@@ -585,7 +613,20 @@
                 return kTRUE;
 
+	   case IDM_kRoqueLampAna:
+  	        Toggle(fOperations, IDM_kRoqueLampAna);
+		//		if (!fDisplay->IsEntryChecked(IDM_kCatalog))
+		if (fOperations->IsEntryChecked(IDM_kRoqueLampAna)) {
+		  fDisplay->CheckEntry(IDM_kStargCaosFilter);
+		}
+		else {
+		  fDisplay->UnCheckEntry(IDM_kStargCaosFilter);
+		}
+		  
+		return kTRUE;
+
+
            case IDM_kStargFindStar:
-                Toggle(fDisplay, IDM_kStargFindStar);         
-		if (fDisplay->IsEntryChecked(IDM_kStargFindStar)) {
+	        Toggle(fDisplay, IDM_kStargFindStar);         
+	        if (fDisplay->IsEntryChecked(IDM_kStargFindStar)) {
 		    fSZdAz->MapWindow();
 		} else {
@@ -615,15 +656,18 @@
 
 		    const Int_t ch0 = 
-			fChannel->IsEntryChecked(IDM_kChannel1) ? 0 : 1;
-                    const Int_t ch1 = 0;
-
-                    if (ch0!=ch1)
-		    {
-
+		      fChannel->IsEntryChecked(IDM_kChannel1) ? 0 : 1;
+		    const Int_t ch1 = 0;
+		    
+		    if (ch0!=ch1)
+		      {
 			delete fGetter;
 			usleep(150000); // FIX: Device or resource busy.
-			fGetter = new Camera(*this, ch1);
-			((Camera*)fGetter)->Loop(0);
-		    }
+			if (fChannel->IsEntryChecked(IDM_kChannel3)) {
+			  fGetter=new PngReader(*this);
+			} else {		      
+			  fGetter = new Camera(*this, ch1);
+			  ((Camera*)fGetter)->Loop(0);
+			}
+		      }
 
 		    fChannel->CheckEntry(IDM_kChannel1);
@@ -854,6 +898,11 @@
                     delete fGetter;
                     usleep(150000); // FIX: Device or resource busy.
-                    fGetter = new Camera(*this, ch1);
-                    ((Camera*)fGetter)->Loop(0);
+		    if (fChannel->IsEntryChecked(IDM_kChannel3))
+		      fGetter=new PngReader(*this);
+		    else
+		      {
+			fGetter = new Camera(*this, ch1);
+			((Camera*)fGetter)->Loop(0);
+		      }
                 }
                 return kTRUE;
@@ -1109,5 +1158,5 @@
 }
 
-ZdAz MStarguider::FindStar(FilterLed &f, FilterLed &f2, Ring &center, MTime &t, Double_t cut, Double_t box, Double_t scalefactor = 1.0)
+XY MStarguider::FindRoqueLamp(FilterLed &f, FilterLed &f2, Ring &CameraCenter, MTime &t, Double_t cut, Double_t box, XY SearchCenter)
 {
     // Set search Paremeters (FIXME: Get them from user input!)
@@ -1117,5 +1166,43 @@
     // Try to find Led in this area
     Leds leds;
-    f.FindStar(leds, (Int_t)center.GetX(), (Int_t)center.GetY());
+    f.FindStarCircle(leds, (Int_t)SearchCenter.X(), (Int_t)SearchCenter.Y());
+
+    // Check whether star found
+    Led *star = (Led*)leds.At(0);
+    if (!star || leds.GetEntries()<1)
+        return XY(.0,.0);
+
+//    cout << "Found Roque Lamp @ " << flush;
+    star->Print();
+    f.MarkPoint(star->GetX(), star->GetY(), 500);
+
+//    cout << "RoquePos: " << star->GetX() << "," << star->GetY() << endl;
+
+    XY roquepos(star->GetX(), star->GetY());
+    XY relroquepos(roquepos.X()-CameraCenter.GetX(), roquepos.Y()-CameraCenter.GetY());
+
+    // If no file open: open new Roque Lamp file
+    if (!fOutRq)
+    {
+        const TString name = MCosy::GetFileName("tpoint/starg_roquelamp_%s.txt");
+        cout << "Starg_RoqueLamp File ********* " << name << " ********** " << endl;
+        fOutRq = new ofstream(name);
+        *fOutRq << "# Magic Roque Lamp file  " << t << endl;
+    }
+
+
+    return relroquepos;
+}
+  
+
+ZdAz MStarguider::FindStar(FilterLed &f, FilterLed &f2, Ring &center, MTime &t, Double_t cut, Double_t box, Double_t scalefactor = 1.0)
+{
+    // Set search Paremeters (FIXME: Get them from user input!)
+    f.SetCut(cut);  // 3.5
+    f.SetBox(box);  // 70
+
+    // Try to find Led in this area
+    Leds leds;
+    f.FindStarCircle(leds, (Int_t)center.GetX(), (Int_t)center.GetY());
 
     // Check whether star found
@@ -1329,4 +1416,7 @@
             pos = fCosy->GetPointingPos();
         center = fCaos->Run(img, printl, printr, pos, t, 50, 3.0);
+
+	cout << "Caos Filter Camera center position: " << center.GetX() << " " << center.GetY() << endl;
+
     }
 
@@ -1390,4 +1480,63 @@
     }
 
+// Find Roque Lamp
+
+    if (fOperations->IsEntryChecked(IDM_kRoqueLampAna)) {
+
+	XY roquelamp(0,0);
+
+	Double_t imageclean = 1.5;
+	Double_t boxradius = 60;
+	Double_t scalefactor = 1;
+	XY searchcenter(768/2-1,576/2+25);
+
+	roquelamp = FindRoqueLamp(f, f2, sgcenter, t, imageclean, boxradius, searchcenter);
+
+	if (fOutRq) {
+	  ZdAz pos = fCosy->GetPointingPos();
+
+	  *fOutRq << "RoqueLampDirect:    " << MTime(-1) << "  " 
+	          << pos.Zd() << " " << pos.Az() << "   "
+		  << roquelamp.X() << " " << roquelamp.Y() << endl;
+	}
+
+	cout << "Starguider Camera Center: " << sgcenter.GetX() << "," << sgcenter.GetY() << endl;
+	cout << ">=>=>=> Roque Lamp found at:         >=>=>=> (" << roquelamp.X() << "," 
+	     << roquelamp.Y() << ") <=<=<=<" << endl;
+
+    }
+
+// Find Spot on Camera Center in Starguider camera
+
+    if (fOperations->IsEntryChecked(IDM_kRoqueLampAna)) {
+
+	XY cameraspot(0,0);
+
+	Double_t imageclean = 5;
+	Double_t boxradius = 60;
+	Double_t scalefactor = 1;
+	//	XY searchcenter(sgcenter.GetX(),sgcenter.GetY());
+	XY searchcenter(60.,290.);
+
+	cameraspot = FindRoqueLamp(f, f2, sgcenter, t, imageclean, boxradius, searchcenter);
+
+	if (fOutRq) {
+	  ZdAz pos = fCosy->GetPointingPos();
+
+	  *fOutRq << "RoqueLampReflected: "  << MTime(-1) << "  "
+		  << pos.Zd() << " " << pos.Az() << "   "
+		  << cameraspot.X() << " " << cameraspot.Y() << endl;
+	}
+
+	cout << ">>>>> Spot on Magic camera found at: >>>>> (" << cameraspot.X() << "," 
+	     << cameraspot.Y() << ") <<<<<" << endl;
+
+        f2.DrawCircle(sgcenter, 5.0, 0x0fa);
+        f2.DrawCircle(sgcenter, 115.0, 0x0fa);
+
+    }
+
+
+
     // we calculate the offset given by the three ETH Leds visible to
     // the guide camera
@@ -1451,4 +1600,5 @@
   	    Leds spots;
   	    f.SetBox(230);
+//	    f.SetCut(1.5);
 	    double bright;
   	    f.ExecuteAndMark(spots, 530, 292, bright);
@@ -1528,5 +1678,6 @@
     if (fDisplay->IsEntryChecked(IDM_kCaosFilter) ||
         fDisplay->IsEntryChecked(IDM_kCatalog)    ||
-        fDisplay->IsEntryChecked(IDM_kFindStar))
+        fDisplay->IsEntryChecked(IDM_kFindStar)   ||
+	fOperations->IsEntryChecked(IDM_kRoqueLampAna)) 
         fImage->DrawColImg(img, cimg);
     else
Index: trunk/MagicSoft/Cosy/main/MStarguider.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MStarguider.h	(revision 7229)
+++ trunk/MagicSoft/Cosy/main/MStarguider.h	(revision 7230)
@@ -67,4 +67,6 @@
     MGPopupMenu   *fChannel;
 
+    MGPopupMenu   *fOperations;
+
     MGPopupMenu   *fCaosWrite;
     MGPopupMenu   *fCaosPrint;
@@ -104,4 +106,5 @@
 
     ofstream *fOutTp;
+    ofstream *fOutRq;
 
     Int_t fDx;
@@ -121,4 +124,8 @@
     ZdAz TrackingError(TArrayF &alt, TArrayF &az, TArrayF &mag) const;
     bool Interpolate(const unsigned long n, byte *img) const;
+
+    XY FindRoqueLamp(FilterLed &f, FilterLed &f2, Ring &CameraCenter, MTime &t, 
+		     Double_t cut, Double_t box, XY SearchCenter);
+
     ZdAz FindStar(FilterLed &f, FilterLed &f2, Ring &center, MTime &t, 
 		  Double_t cut, Double_t box, Double_t scalefactor);
Index: trunk/MagicSoft/Cosy/main/MTracking.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MTracking.cc	(revision 7229)
+++ trunk/MagicSoft/Cosy/main/MTracking.cc	(revision 7230)
@@ -244,10 +244,58 @@
 ZdAz MTracking::GetPointingPosRE(Bool_t pdo) const
 {
-    // Conversion factor from se to re
-    const XY re = fCosy->kGearTot/fCosy->kResSE; //[re/se]
-
-    Int_t pzd1 = fCosy->fZd1->GetPos();
-    Int_t pzd2 = fCosy->fZd2->GetPos();
-    Int_t paz  = fCosy->fAz->GetPos();
+     // Conversion factor from se to re
+     const XY re = fCosy->kGearTot/fCosy->kResSE; //[re/se]
+
+     const bool bool1 = fCosy->fZd1->DirHasChanged();
+     const bool bool2 = fCosy->fZd2->DirHasChanged();
+
+     if (bool1 && bool2) {
+       fCosy->fZd1->ResetDirHasChanged();
+       fCosy->fZd2->ResetDirHasChanged();
+     }
+ 
+     Int_t pzd1 = !bool1 ? fCosy->fZd1->GetPos() : fCosy->fZd1->GetDirChangedPos();
+     Int_t pzd2 = !bool2 ? fCosy->fZd2->GetPos() : fCosy->fZd2->GetDirChangedPos();
+     Int_t paz  =          fCosy->fAz->GetPos();
+ 
+     // Get current shaftencoder position of the telescope
+     Double_t seposzd1 = ((pzd1+8192)%16384)*re.X();
+     Double_t seposzd2 = ((pzd2+8192)%16384)*re.X();
+     Double_t seposaz  =   paz              *re.Y();
+ 
+     // distance between (To+dt) and To [re]
+     // position time difference < 5usec
+     // fRePos does the synchronization between the
+     // Shaft- and the rotary encoders
+     const ZdAz repos = pdo ? fCosy->GetRePosPdo() : fCosy->GetRePos();
+ 
+     const Int_t offset1 = !bool1 ? fCosy->fZd1->GetOffset() : fCosy->fZd1->GetDirChangedOffset();
+     const Int_t offset2 = !bool2 ? fCosy->fZd2->GetOffset() : fCosy->fZd2->GetDirChangedOffset();
+ 
+     // Calculate the part of one SE which the motors moved
+     // since the last SE has changed its value
+     const Double_t offzd1 = repos.Zd() - offset1;
+     const Double_t offzd2 = repos.Zd() - offset2;
+     const Double_t offaz  = repos.Az() - fCosy->fAz->GetOffset();
+ 
+     // Correct for the direction in which the motor is moving
+     // (in which the shaftencoders should change its values)
+     if (offaz<0)
+         seposaz += re.Y();
+     if (offzd1<0)
+         seposzd1 += re.X();
+     if (offzd2<0)
+         seposzd2 += re.X();
+ 
+     // and interpolate the shaftencoder steps using the motor
+     // encoder positon (Be carefull the minus-sign is important)
+     seposzd1 += offzd1;
+     seposzd2 -= offzd2;
+     seposaz  += offaz;
+ 
+
+
+     return ZdAz((seposzd1-seposzd2)/2, seposaz);
+}
 /*
     if (fCosy->fZd1->DirHasChanged() != fCosy->fZd2->DirHasChanged())
@@ -262,38 +310,4 @@
     }
   */
-    // Get current shaftencoder position of the telescope
-    Double_t seposzd1 = ((pzd1+8192)%16384)*re.X();
-    Double_t seposzd2 = ((pzd2+8192)%16384)*re.X();
-    Double_t seposaz  =   paz              *re.Y();
-
-    // distance between (To+dt) and To [re]
-    // position time difference < 5usec
-    // fRePos does the synchronization between the
-    // Shaft- and the rotary encoders
-    const ZdAz repos = pdo ? fCosy->GetRePosPdo() : fCosy->GetRePos();
-
-    // Calculate the part of one SE which the motors moved
-    // since the last SE has changed its value
-    const Double_t offzd1 = repos.Zd() - fCosy->fZd1->GetOffset();
-    const Double_t offzd2 = repos.Zd() - fCosy->fZd2->GetOffset();
-    const Double_t offaz  = repos.Az() - fCosy->fAz->GetOffset();
-
-    // Correct for the direction in which the motor is moving
-    // (in which the shaftencoders should change its values)
-    if (offaz<0)
-        seposaz += re.Y();
-    if (offzd1<0)
-        seposzd1 += re.X();
-    if (offzd2<0)
-        seposzd2 += re.X();
-
-    // and interpolate the shaftencoder steps using the motor
-    // encoder positon (Be carefull the minus-sign is important)
-    seposzd1 += offzd1;
-    seposzd2 -= offzd2;
-    seposaz  += offaz;
-
-    return ZdAz((seposzd1-seposzd2)/2, seposaz);
-}
 
 void MTracking::TrackPosition(const RaDec &dst) // ra, dec [rad]
Index: trunk/MagicSoft/Cosy/videodev/FilterLed.cc
===================================================================
--- trunk/MagicSoft/Cosy/videodev/FilterLed.cc	(revision 7229)
+++ trunk/MagicSoft/Cosy/videodev/FilterLed.cc	(revision 7230)
@@ -120,4 +120,67 @@
     return GetMeanPosition(x, y, box, mx, my, sum);
 }
+
+int FilterLed::GetMeanPositionCircle(const int x, const int y,
+				     const int box, float &mx, 
+				     float &my, unsigned int &sum) const
+{
+    unsigned int sumx=0;
+    unsigned int sumy=0;
+
+    //-------------------------------
+    // Improved algorithm:
+    // 1. Look for the largest four-pixel signal inside box
+
+    int thissum=0, maxsum=0;
+    int maxx=0, maxy=0;
+    for (int dx=x-box; dx<x+box+1; dx++)
+        for (int dy=y-box; dy<y+box+1; dy++)
+        {
+            thissum = fImg[dy*fW+dx]+fImg[(dy+1)*fW+dx]+
+	      fImg[dy*fW+(dx+1)]+fImg[(dy+1)*fW+(dx+1)];
+	    if(thissum>maxsum)
+	      {
+		maxx=dx;
+		maxy=dy;
+		maxsum=thissum;
+	      }
+	}
+
+    // 2. Calculate mean position inside a circle around
+    // the highst four-pixel signal with radius of 5 pixels.
+
+    sum=0;
+    for (int dx=x-box; dx<x+box+1; dx++)
+        for (int dy=y-box; dy<y+box+1; dy++)
+        {
+            const byte &m = fImg[dy*fW+dx];
+
+	    // Circle
+	    if(sqrt((dx-maxx)*(dx-maxx)+
+		    (dy-maxy)*(dy-maxy)) <= 6)
+	      {
+		sumx += m*dx;
+		sumy += m*dy;
+		sum  += m;
+	      }
+        }
+
+    mx = (float)sumx/sum;
+    my = (float)sumy/sum;
+
+    return (int)my*fW + (int)mx;
+}
+
+
+
+int FilterLed::GetMeanPositionCircle(const int x, const int y, 
+				     const int box) const
+{
+    float mx, my;
+    unsigned int sum;
+    return GetMeanPositionCircle(x, y, box, mx, my, sum);
+}
+
+
 /*
 void FilterLed::RemoveTwins(Leds &leds, Double_t radius)
@@ -486,4 +549,124 @@
 }
 
+void FilterLed::FindStarCircle(Leds &leds, int xc, int yc) const
+{
+    // fBox: radius of the inner (signal) box
+    // Radius of the outer box is fBox*sqrt(2)
+
+    //
+    // Define inner box in which to search the signal
+    //
+    int x0 = xc-fBox;
+    int x1 = xc+fBox;
+    int y0 = yc-fBox;
+    int y1 = yc+fBox;
+
+    if (x0<0) x0=0;
+    if (y0<0) y0=0;
+    if (x1>fW) x1=fW;
+    if (y1>fH) y1=fH;
+
+    //
+    // Define outer box (excluding inner box) having almost
+    // the same number of pixels in which the background
+    // is calculated
+    //
+    const double sqrt2 = sqrt(2.);
+
+    int xa = xc-(int)rint(fBox*sqrt2);
+    int xb = xc+(int)rint(fBox*sqrt2);
+    int ya = yc-(int)rint(fBox*sqrt2);
+    int yb = yc+(int)rint(fBox*sqrt2);
+
+    if (xa<0) xa=0;
+    if (ya<0) ya=0;
+    if (xb>fW) xb=fW;
+    if (yb>fH) yb=fH;
+
+    //
+    // Calculate average and sdev for a square
+    // excluding the inner part were we expect
+    // the signal to be.
+    //
+    double sum = 0;
+    double sq  = 0;
+
+    int n=0;
+    for (int x=xa; x<xb; x++)
+        for (int y=ya; y<yb; y++)
+        {
+            if (x>=x0 && x<x1 && y>=y0 && y<y1)
+                continue;
+
+            byte &b = fImg[y*fW+x];
+
+            sum += b;
+            sq  += b*b;
+            n++;
+        }
+
+    sum /= n;
+    sq  /= n;
+
+    // 254 because b<=max and not b<max
+    const double sdev = sqrt(sq-sum*sum);
+    const byte   max  = sum+fCut*sdev>254 ? 254 : (byte)(sum+fCut*sdev);
+
+    //
+    // clean image from noise
+    // (FIXME: A lookup table could accelerate things...
+    //
+    n=0;
+    for (int x=x0; x<x1; x++)
+        for (int y=y0; y<y1; y++)
+        {
+            byte &b = fImg[y*fW+x];
+            if (b<=max)
+                b = 0;
+            else
+                n++;
+        }
+
+    //
+    // Mark the background region
+    //
+    for (int x=xa; x<xb; x+=2)
+    {
+        fImg[ya*fW+x]=0xf0;
+        fImg[yb*fW+x]=0xf0;
+    }
+    for (int y=ya; y<yb; y+=2)
+    {
+        fImg[y*fW+xa]=0xf0;
+        fImg[y*fW+xb]=0xf0;
+    }
+
+    //
+    // Check if any pixel found...
+    //
+    if (n<5)
+        return;
+
+    //
+    // Get the mean position of the star
+    //
+    float mx, my;
+    unsigned int mag;
+
+    //    int pos = GetMeanPosition(xc, yc, fBox-1, mx, my, mag);
+
+    // try new method
+    int pos = GetMeanPositionCircle(xc, yc, fBox-1, mx, my, mag);
+    
+    if (pos<0 || pos>=fW*fH && fImg[pos]<sum+fCut*sdev)
+        return;
+
+    cout << "Mean=" << sum << "  SDev=" << sdev << "  :  ";
+    cout << "Sum/n = " << sum << "/" << n << " = " << (n==0?0:mag/n) << endl;
+
+    leds.Add(mx, my, 0, 0, -2.5*log10((float)mag)+13.7);
+}
+
+
 void FilterLed::Stretch() const
 {
Index: trunk/MagicSoft/Cosy/videodev/FilterLed.h
===================================================================
--- trunk/MagicSoft/Cosy/videodev/FilterLed.h	(revision 7229)
+++ trunk/MagicSoft/Cosy/videodev/FilterLed.h	(revision 7230)
@@ -24,4 +24,11 @@
     int  GetMeanPosition(const int x, const int y, const int box, 
 			 float &mx, float &my, unsigned int &sum) const;
+
+    int  GetMeanPositionCircle(const int x, const int y, 
+			       const int box) const;
+    int  GetMeanPositionCircle(const int x, const int y, 
+			       const int box, float &mx, float &my, 
+			       unsigned int &sum) const;
+
     void RemoveTwinsInterpol(Leds &leds, Int_t first, Double_t radius) const;
     void DrawBox(const int x1, const int y1,
@@ -43,4 +50,6 @@
     void SetCut(float cut) { fCut = cut; } 
     void FindStar(Leds &leds, int xc, int yc) const;
+    void FindStarCircle(Leds &leds, int xc, int yc) const;
+    
     void Execute(Leds &leds, int xc, int yc, double &bright) const;
     void Execute(Leds &leds, int xc, int yc) const;
