Index: trunk/MagicSoft/Cosy/.cosyrc_magic
===================================================================
--- trunk/MagicSoft/Cosy/.cosyrc_magic	(revision 4075)
+++ trunk/MagicSoft/Cosy/.cosyrc_magic	(revision 4076)
@@ -1,18 +1,34 @@
+#
+# .cosyrc
+#
+# Default values are commented out
+# 
 
+# Number of motor revolution necessary to turn the
+# telescope 360deg. (Remark: Here we do not talk about 
+# revolutions of the 'real' motor, but about revolutions
+# 'seen' by the Macs)
 Az_GearRatio[U_mot/U_tel]: 1338.8
-# 1338.3
 Zd_GearRatio[U_mot/U_tel]: 1165.2
-# old value: 1165.2, try: 1211.8
-#1149.5
-#1208.29
 
+# CANbus Id of the three MACS. -1 means not connected.
+# MAC1 is Azimuth-1
+# MAC2 is Azimuth-2
+# MAC  is Zenith Angle
 Az_Id-MAC1:  1
 Az_Id-MAC2: -1
 Zd_Id-MAC:   3
 
+# CANbus Id of the three Shaftencoders.
+# SE1 is Zenith Angle-1
+# SE2 is Zenith Angle-2
+# SE  is Azimuth
 Az_Id-SE:  16
 Zd_Id-SE1: 17
 Zd_Id-SE2: 18
 
-
-
+# Software endswitch
+#Az_Min[deg]:  -95.0
+#Zd_Min[deg]:  -75.0
+#Az_Max[deg]:  305.0
+#Zd_Max[deg]:   98.25
Index: trunk/MagicSoft/Cosy/Changelog
===================================================================
--- trunk/MagicSoft/Cosy/Changelog	(revision 4075)
+++ trunk/MagicSoft/Cosy/Changelog	(revision 4076)
@@ -1,3 +1,127 @@
                                                                   -*-*- END -*-*-
+ 2004/05/15 - Thomas Bretz (La Palma)
+
+   * .cosyrc_magic:
+     - updated with some comments
+
+   * Makefile:
+     - added many more links necessary for current make
+       (should be replaced by libmars.so in the future)
+
+   * Makefile.conf.general:
+     - added GX11 and HistPainter
+
+   * cosy.cc, starg.cc:
+     - Moved initialization of Camera to MStarguider
+     - added command line option to choose ccd channel
+
+   * leds.txt:
+     - replaced with new LED positions (OFFSETS MISSING)
+
+   * stars.txt:
+     - added many more stars
+
+   * base/coord.h:
+     - added operator/=(XY&)
+
+   * base/msgqueue.cc, candrv/sdolist.cc:
+     - added more output in case mutex is already locked by the same thread
+
+   * candrv/vmodican.cc:
+     - some changes to output
+
+   * catalog/SlaStars.cc:
+     - changed some comments
+
+   * catalog/StarCatalog.[h,cc]:
+     - replaced old algorithms by MAstroCatalog and new simplifications
+       to calculate star-positions accuratly by combining slalib with
+       MAstroCatalog
+
+   * devdrv/macs.h:
+     - added GetPosTime
+
+   * devdrv/shaftencoder.[h,cc]:
+     - added output to report file
+
+   * gui/MGAccuracy.[h,cc]:
+     - added time development curve (blue)
+
+   * gui/MGEmbeddedCanvas.h, gui/MGSkyPosition.h, 
+     gui/MGVelocity.h:
+     - changed ifndef define
+
+   * gui/MGImage.[h,cc]:
+     - enhancements in speed
+     - enhancements in mutex locking mechanism
+
+   * gui/MGPngReader.cc, gui/MGTPoint.cc:
+     - changed meaning of PixSize
+
+   * gui/MGVelocity.cc:
+     - fixed units
+
+   * main/MCaos.[h,cc]:
+     - changed ring radius from 266/272 to 266,268
+     - moved drawing circles to MStarguider
+
+   * main/MCosy.[h,cc]:
+     - moved big parts of the code to MPointing and MTracking
+     - removed old conversion constants (Se to RE, etc) and
+       replaced by more meaningful ones
+     - prepare displaying starguider image
+     - added GetFileName to globally prepare correct file names
+
+   * main/MPointing.cc:
+     - fixed missing SetDecelaration
+     - changed to new unit conversion constants
+     - Use SendStatus instead of Send
+
+   * main/MStarguider.cc:
+     - added update and support of cosy-image display
+     - added channel swicthing for the frame grabber
+     - added algorithm to find star position FindStar
+     - commented out starguider algorithms
+     - draw support lines and grid stuff
+
+   * main/MTracking.[h,cc]:
+     - changed to new unit conversion constants
+     - added output of RE stuff to report file
+     - some simplification to tracking thread
+
+   * base/MString.[h,cc]:
+     - added as a thread safe replacement for Form()
+
+   * tcpip/MCeCoCom.[h,cc]:
+     - changed support for Weather information
+
+   * tcpip/MDriveCom.[h,cc]:
+     - changed output
+     - added SendStatus
+
+   * tcpip/MTcpIpIO.cc:
+     - changed output
+     - output reports to report file
+
+   * tpoint/gui.C:
+     - read new starg_* files
+
+   * videodev/Camera.[h,cc]:
+     - some enhancements to ioctl call
+     - some changes to output
+     - changes a bit the bahaviour of mutices
+     - replaced fRunning by mutex
+     - changes to ExitLoop and IsRunning
+     - added support for several frame grabber channels
+
+   * videodev/FilterLed.[h,cc]
+     - added new algorithms to find star
+     - small updates to star finding support
+
+   * videodev/PixGetter.h:
+     - added a virtual empty destructor (IMPORTANT)
+
+
+
  2003/12/29 - Thomas Bretz
 
Index: trunk/MagicSoft/Cosy/Makefile
===================================================================
--- trunk/MagicSoft/Cosy/Makefile	(revision 4075)
+++ trunk/MagicSoft/Cosy/Makefile	(revision 4076)
@@ -127,18 +127,50 @@
 links:
 	@ln -sf ../../Mars/mbase/MAGIC.h base/MAGIC.h
-	@ln -sf ../../Mars/mbase/MLog.h base/MLog.h
+	@ln -sf ../../Mars/mbase/MLog.h  base/MLog.h
 	@ln -sf ../../Mars/mbase/MLog.cc base/MLog.cc
-	@ln -sf ../../Mars/mbase/MLogManip.h base/MLogManip.h
+	@ln -sf ../../Mars/mbase/MLogPlugin.h  base/MLogPlugin.h
+	@ln -sf ../../Mars/mbase/MLogPlugin.cc base/MLogPlugin.cc
+	@ln -sf ../../Mars/mbase/MLogManip.h  base/MLogManip.h
 	@ln -sf ../../Mars/mbase/MLogManip.cc base/MLogManip.cc
-	@ln -sf ../../Mars/mbase/MAstro.h base/MAstro.h
-	@ln -sf ../../Mars/mbase/MAstro.cc base/MAstro.cc
-	@ln -sf ../../Mars/mbase/MGList.h base/MGList.h
+	@ln -sf ../../Mars/mbase/MGList.h  base/MGList.h
 	@ln -sf ../../Mars/mbase/MGList.cc base/MGList.cc
-	@ln -sf ../../Mars/mbase/MTime.h base/MTime.h
+	@ln -sf ../../Mars/mbase/MTime.h  base/MTime.h
 	@ln -sf ../../Mars/mbase/MTime.cc base/MTime.cc
-	@ln -sf ../../Mars/mbase/MParContainer.h base/MParContainer.h
+	@ln -sf ../../Mars/mbase/MParContainer.h  base/MParContainer.h
 	@ln -sf ../../Mars/mbase/MParContainer.cc base/MParContainer.cc
-	@ln -sf ../../Mars/mtemp/MObservatory.h base/MObservatory.h
-	@ln -sf ../../Mars/mtemp/MObservatory.cc base/MObservatory.cc
+	@ln -sf ../../Mars/mbase/MString.h  base/MString.h
+	@ln -sf ../../Mars/mbase/MString.cc base/MString.cc
+	@ln -sf ../../Mars/mbase/MGMap.h  base/MGMap.h
+	@ln -sf ../../Mars/mbase/MGMap.cc base/MGMap.cc
+	@ln -sf ../../Mars/mgeom/MGeomMirror.h  base/MGeomMirror.h
+	@ln -sf ../../Mars/mgeom/MGeomMirror.cc  base/MGeomMirror.cc
+	@ln -sf ../../Mars/mgeom/MGeomCam.h  base/MGeomCam.h
+	@ln -sf ../../Mars/mgeom/MGeomCam.cc base/MGeomCam.cc
+	@ln -sf ../../Mars/mgeom/MGeomPix.h  base/MGeomPix.h
+	@ln -sf ../../Mars/mgeom/MGeomPix.cc base/MGeomPix.cc
+	@ln -sf ../../Mars/mgeom/MGeomCamMagic.h  base/MGeomCamMagic.h
+	@ln -sf ../../Mars/mgeom/MGeomCamMagic.cc base/MGeomCamMagic.cc
+	@ln -sf ../../Mars/mastro/MAstro.h  base/MAstro.h
+	@ln -sf ../../Mars/mastro/MAstro.cc base/MAstro.cc
+	@ln -sf ../../Mars/mastro/MAstroCatalog.h  base/MAstroCatalog.h
+	@ln -sf ../../Mars/mastro/MAstroCatalog.cc base/MAstroCatalog.cc
+	@ln -sf ../../Mars/mastro/MAstroCamera.h  base/MAstroCamera.h
+	@ln -sf ../../Mars/mastro/MAstroCamera.cc base/MAstroCamera.cc
+	@ln -sf ../../Mars/mastro/MAstroSky2Local.h  base/MAstroSky2Local.h
+	@ln -sf ../../Mars/mastro/MAstroSky2Local.cc base/MAstroSky2Local.cc
+	@ln -sf ../../Mars/mastro/MObservatory.h  base/MObservatory.h
+	@ln -sf ../../Mars/mastro/MObservatory.cc base/MObservatory.cc
+	@ln -sf ../../Mars/mhist/MHCamera.h base/MHCamera.h
+	@ln -sf ../../Mars/mhist/MHCamera.cc base/MHCamera.cc
+	@ln -sf ../../Mars/mhbase/MH.h base/MH.h
+	@ln -sf ../../Mars/mhbase/MH.cc base/MH.cc
+	@ln -sf ../../Mars/mhbase/MBinning.h base/MBinning.h
+	@ln -sf ../../Mars/mhbase/MBinning.cc base/MBinning.cc
+	@ln -sf ../../Mars/mbase/MParList.h base/MParList.h
+	@ln -sf ../../Mars/mbase/MParList.cc base/MParList.cc
+	@ln -sf ../../Mars/mgui/MHexagon.h base/MHexagon.h
+	@ln -sf ../../Mars/mgui/MHexagon.cc base/MHexagon.cc
+	@ln -sf ../../Mars/mgui/MCamEvent.h base/MCamEvent.h
+	@ln -sf ../../Mars/mgui/MCamEvent.cc base/MCamEvent.cc
 
 magic:
Index: trunk/MagicSoft/Cosy/Makefile.conf.general
===================================================================
--- trunk/MagicSoft/Cosy/Makefile.conf.general	(revision 4075)
+++ trunk/MagicSoft/Cosy/Makefile.conf.general	(revision 4076)
@@ -4,6 +4,6 @@
 
 ROOTVER    =  `root-config --version`
-ROOTLIBS   =  `root-config --libs` -lThread
-ROOTGLIBS  =  `root-config --glibs` -lThread
+ROOTLIBS   =  `root-config --libs` -lThread -lGX11 -lHistPainter 
+ROOTGLIBS  =  `root-config --glibs` -lThread -lGX11 -lHistPainter 
 ROOTCFLAGS =  `root-config --cflags`
 
Index: trunk/MagicSoft/Cosy/base/MString.cc
===================================================================
--- trunk/MagicSoft/Cosy/base/MString.cc	(revision 4076)
+++ trunk/MagicSoft/Cosy/base/MString.cc	(revision 4076)
@@ -0,0 +1,4 @@
+#include "MString.h"
+
+ClassImp(MString);
+
Index: trunk/MagicSoft/Cosy/base/MString.h
===================================================================
--- trunk/MagicSoft/Cosy/base/MString.h	(revision 4076)
+++ trunk/MagicSoft/Cosy/base/MString.h	(revision 4076)
@@ -0,0 +1,45 @@
+#ifndef MARS_MString
+#define MARS_MString
+
+#ifndef ROOT_TString
+#include <TString.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+class MString : public TString
+{
+public:
+    MString &Print(const char *fmt, ...)
+    {
+        va_list ap;
+        va_start(ap, fmt);
+
+        Int_t n=256;
+
+        char *ret=0;
+
+        while (1)
+        {
+            ret = new char[n+1];
+            Int_t sz = vsnprintf(ret, n, fmt, ap);
+            if (sz<=n)
+                break;
+
+            n *= 2;
+            delete [] ret;
+        };
+
+        va_end(ap);
+
+        *static_cast<TString*>(this) = ret;
+
+        delete [] ret;
+
+        return *this;
+    }
+    ClassDef(MString, 1)
+};
+
+#endif
Index: trunk/MagicSoft/Cosy/base/coord.h
===================================================================
--- trunk/MagicSoft/Cosy/base/coord.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/base/coord.h	(revision 4076)
@@ -90,4 +90,5 @@
     void Az(double d)  { fY=d; }
     void operator*=(const XY &c)    { fX*=c.X(); fY*=c.Y(); }
+    void operator/=(const XY &c)    { fX/=c.X(); fY/=c.Y(); }
     void operator-=(const AltAz &c) { fX-=c.fX; fY-=c.fY; }
     void operator+=(const AltAz &c) { fX+=c.fX; fY+=c.fY; }
@@ -117,4 +118,5 @@
     void Az(double d) { fY=d; }
     void operator*=(const XY &c)   { fX*=c.X(); fY*=c.Y(); }
+    void operator/=(const XY &c)   { fX/=c.X(); fY/=c.Y(); }
     void operator-=(const ZdAz &c) { fX-=c.fX; fY-=c.fY; }
     void operator+=(const ZdAz &c) { fX+=c.fX; fY+=c.fY; }
Index: trunk/MagicSoft/Cosy/base/msgqueue.cc
===================================================================
--- trunk/MagicSoft/Cosy/base/msgqueue.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/base/msgqueue.cc	(revision 4076)
@@ -89,7 +89,9 @@
         // a PostMsg is processed correctly
         //
-        fMuxMsg.Lock();
+        if (fMuxMsg.Lock()==13)
+            cout << "MsgQueue::Thread - mutex is already locked by this thread." << endl;
         fBreak = 0;
-        fMuxMsg.UnLock();
+        if (fMuxMsg.UnLock()==13)
+            cout << "MsgQueue::Thread - tried to unlock mutex locked by other thread." << endl;
 
 #ifdef DEBUG
@@ -130,5 +132,6 @@
     cout << "MsgQueue::PostMsg: Locking MsgQueue mutex..." << flush;
 #endif
-    fMuxMsg.Lock();
+    if (fMuxMsg.Lock()==13)
+        cout << "MsgQueue::PostMsg - mutex is already locked by this thread." << endl;
 #ifdef DEBUG
     cout << "done." << endl;
@@ -145,5 +148,6 @@
     if (fBreak)
     {
-        fMuxMsg.UnLock();
+        if (fMuxMsg.UnLock()==13)
+            cout << "MsgQueue::PostMsg - tried to unlock mutex locked by other thread." << endl;
 #ifdef DEBUG
         cout << "------------> MsgQueue::PostMsg: Proc still pending... Message IGNORED." << endl;
@@ -176,5 +180,6 @@
 #endif
     fStart = 1;
-    fMuxMsg.UnLock();
+    if (fMuxMsg.UnLock()==13)
+        cout << "MsgQueue::PostMsg - tried to unlock mutex locked by other thread." << endl;
 #ifdef DEBUG
     cout << "done." << endl;
Index: trunk/MagicSoft/Cosy/candrv/sdolist.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/sdolist.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/candrv/sdolist.cc	(revision 4076)
@@ -20,5 +20,6 @@
 void PendingSDOList::DelAll()
 {
-    fMux.Lock();
+    if (fMux.Lock()==13)
+        cout << "PendingSDOList::DelAll - mutex is already locked by this thread" << endl;
 
     PendingSDO *prev = fFirst;
@@ -35,5 +36,6 @@
     fLast  = fFirst;
 
-    fMux.UnLock();
+    if (fMux.UnLock()==13)
+        cout << "PendingSDOList::DelAll - tried to unlock mutex locked by other thread." << endl;
 }
 
@@ -42,5 +44,6 @@
     PendingSDO *sdo = fFirst;
 
-    fMux.Lock();
+    if (fMux.Lock()==13)
+        cout << "PendingSDOList::Add - mutex is already locked by this thread" << endl;
     while ((sdo=sdo->Next))
         if (sdo->Node==node && sdo->Idx==idx && sdo->Subidx==subidx)
@@ -54,5 +57,6 @@
     fLast->Next = new PendingSDO(node, idx, subidx);
     fLast = fLast->Next;
-    fMux.UnLock();
+    if (fMux.UnLock()==13)
+        cout << "PendingSDOList::Add - tried to unlock mutex locked by other thread." << endl;
 }
 
@@ -62,5 +66,6 @@
     PendingSDO *sdo;
 
-    fMux.Lock();
+    if (fMux.Lock()==13)
+        cout << "PendingSDOList::Del - mutex is already locked by this thread" << endl;
     while ((sdo=prev->Next))
     {
@@ -80,5 +85,6 @@
         break;
     }
-    fMux.UnLock();
+    if (fMux.UnLock()==13)
+        cout << "PendingSDOList::Del - tried to unlock mutex locked by other thread." << endl;
 }
 
@@ -93,5 +99,6 @@
     PendingSDO *sdo = fFirst;
 
-    fMux.Lock();
+    if (fMux.Lock()==13)
+        cout << "PendingSDOList::IsPending(byte) - mutex is already locked by this thread" << endl;
     while ((sdo=sdo->Next))
         if (sdo->Node==node)
@@ -100,5 +107,6 @@
             break;
         }
-    fMux.UnLock();
+    if (fMux.UnLock()==13)
+        cout << "PendingSDOList::IsPending(byte) - tried to unlock mutex locked by other thread." << endl;
 
     return rc;
@@ -110,5 +118,6 @@
     PendingSDO *sdo = fFirst;
 
-    fMux.Lock();
+    if (fMux.Lock()==13)
+        cout << "PendingSDOList::IsPending - mutex is already locked by this thread" << endl;
     while ((sdo=sdo->Next))
         if (sdo->Node==node && sdo->Idx==idx && sdo->Subidx==subidx)
@@ -117,5 +126,6 @@
             break;
         }
-    fMux.UnLock();
+    if (fMux.UnLock()==13)
+        cout << "PendingSDOList::IsPending - tried to unlock mutex locked by other thread." << endl;
 
     return rc;
Index: trunk/MagicSoft/Cosy/candrv/vmodican.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 4076)
@@ -116,12 +116,10 @@
         unsigned char c;
         const int n = read(fd, &c, 1);
-
         if (n<0)
         {
             cerr << "Vmodican: read(" << dec << (int)fd << "," << (void*)&c;
-            cerr << ",1) returned c=" << (int)c << " '" << strerror(errno);
-            cerr << "' (errno = " << errno << ")" << endl;
+            cerr << ",1) returned rc=" << n << " c=" << (int)c << " '";
+            cerr << strerror(errno) << "' (errno = " << errno << ")" << endl;
             continue;
-            //return (void *)1;
         }
 
@@ -936,5 +934,5 @@
 //  and switch the can bus communication on
 //
-VmodIcan::VmodIcan(const char *dev, const int baud, MLog &out) : Log(out), MThread(false, -10)//: CanDriver(dev, baud)
+VmodIcan::VmodIcan(const char *dev, const int baud, MLog &out) : Log(out), MThread(false, 10)//: CanDriver(dev, baud)
 {
     //
Index: trunk/MagicSoft/Cosy/catalog/SlaStars.cc
===================================================================
--- trunk/MagicSoft/Cosy/catalog/SlaStars.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/catalog/SlaStars.cc	(revision 4076)
@@ -159,6 +159,6 @@
     double az;
     slaAopqk (r, d, (double*)fAoprms,
-              &az,    // observed azimuth (radians: N=0,E=90)
-              &zd,    // observed zenith distance (radians) [-pi/2, pi/2]
+              &az,    // observed azimuth (radians: N=0,E=90) [-pi, pi]
+              &zd,    // observed zenith distance (radians)   [-pi/2, pi/2]
               &h0,    // observed hour angle (radians)
               &d1,    // observed declination (radians)
@@ -175,4 +175,6 @@
 ZdAz SlaStars::GetApproxVel(const RaDec &radec) const // [rad/rad]
 {
+    // radec        [rad]
+    // GetApproxVel [rad/rad]
     double az, vaz, aaz;
     double el, vel, ael;
Index: trunk/MagicSoft/Cosy/catalog/StarCatalog.cc
===================================================================
--- trunk/MagicSoft/Cosy/catalog/StarCatalog.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/catalog/StarCatalog.cc	(revision 4076)
@@ -5,4 +5,5 @@
 
 #include <TSystem.h>
+#include <TRotation.h>
 
 #include "slalib.h"
@@ -11,56 +12,25 @@
 
 #include "MStarList.h"
+#include "MAstroCatalog.h"
 
 ClassImp(StarCatalog);
 
-StarCatalog::StarCatalog(MObservatory::LocationName_t key) : SlaStars(key), fSao(NULL), fSrt(NULL), fEntries(0), fSinAngle(0), fCosAngle(1)
-{
-    // p = pointer to MainFrame (not owner)
-
-    //
-    // read index file
-    //
-    File idx("sao/sao-sort.idx", "r");
-    if (!idx)
-        return;
-
-    while (!idx.Eof())
-    {
-        idx.Newline();
-        fEntries++;
-    }
-
-    idx.Reset();
-
-    fSrt = new sort_t[fEntries];
-
-    for (int i=0; i<fEntries; i++)
-    {
-        fSrt[i].ra  = idx.Geti(4);
-        fSrt[i].dec = idx.Geti(4);
-        fSrt[i].nr  = idx.Geti(10);
-        idx.Newline();
-    }
-
-    //
-    // open catalog
-    //
-    fSao = new SaoFile("sao/sao-sort.cmp");
+StarCatalog::StarCatalog(MObservatory::LocationName_t key) : SlaStars(key), fAstro(0), /*fSao(NULL), fSrt(NULL), fEntries(0),*/ fSinAngle(0), fCosAngle(1)
+{
+    fAstro = new MAstroCatalog;
+    fAstro->SetObservatory(*this);
+    fAstro->SetPlainScreen();
 }
 
 StarCatalog::~StarCatalog()
 {
-    if (fSrt)
-        delete fSrt;
-    if (fSao)
-        delete fSao;
+    delete fAstro;
 }
 
 void StarCatalog::SetPixSize(const double pixsize)
 {
-    fPixSize = D2PI/360.0 * pixsize;
-
-    fWidth  = fPixSize * 768/2;
-    fHeight = fPixSize * 576/2;
+    // pixsize [arcsec/pixel]
+    fPixSize = D2PI/360.0*pixsize/3600; // [rad / (deg*pixel)]
+    fAstro->SetRadiusFOV(pixsize, 768, 576);
 }
 
@@ -70,328 +40,47 @@
 }
 
+void StarCatalog::SetLimitMag(const float mag)
+{
+    fLimitMag = mag;
+    fAstro->SetLimMag(mag);
+}
+
+void StarCatalog::SetMjd(double mjd)
+{
+    SlaStars::SetMjd(mjd);
+    fAstro->SetTime(MTime(mjd));
+}
 
 void StarCatalog::SetAltAz(const AltAz &altaz)
 {
     fAltAz = altaz * D2PI/360.0;
-
-    cout << "Set --> Alt: " << 360.0/D2PI*fAltAz.Alt();
-    cout << "  Az: " << fAltAz.Az() << endl;
-
     fRaDec = CalcRaDec(fAltAz);
 
-    cout << "Ra: " << 360.0/D2PI*fRaDec.Ra();
-    cout << "  Dec: " << 360.0/D2PI*fRaDec.Dec() << endl;
-
-    CalcAltAzRange();
-    CalcRaDecRange();
+    fAstro->SetRaDec(fRaDec.Ra(), fRaDec.Dec());
+}
+
+void StarCatalog::Reload()
+{
+    fAstro->SetLimMag(99);
+    //fAstro->ReadBSC("bsc5.dat");
+    //fAstro->ReadHeasarcPPM("heasarc_ppm.tdat");
+    fAstro->ReadCompressed("ppm9.bin");
+    fAstro->SetLimMag(fLimitMag);
 }
 
 void StarCatalog::SetRaDec(const RaDec &radec)
 {
-    fRaDec = radec;
-    fRaDec *= D2PI/360.0;
-
+    const RaDec rd = fRaDec*360.0/D2PI;;
+
+    const Bool_t same =
+        rd.Ra() >radec.Ra() -1e-5 && rd.Ra() <radec.Ra() +1e-5 &&
+        rd.Dec()>radec.Dec()-1e-5 && rd.Dec()<radec.Dec()+1e-5;
+
+    fRaDec = radec * D2PI/360.0;
     fAltAz = CalcAltAz(fRaDec);
 
-    //cout << "Alt: " << 360.0/D2PI*fAltAz.Alt() << "  ";
-    //cout << "Az: "  << 360.0/D2PI*fAltAz.Az()  << endl;
-
-    CalcRaDecRange();
-    CalcAltAzRange();
-}
-
-void StarCatalog::CalcAltAzRange()
-{
-    byte fAlt0[180];
-
-    for (int h=0; h<180; h++)
-        fAlt0[h] = kFALSE;
-
-    for (int h=0; h<360; h++)
-        fAz0[h] = kFALSE;
-
-    double az0, alt0;
-    double az1, alt1;
-    //
-    // scan horizontal border
-    //
-    for (int x=-768/2; x<768/2+1; x++)
-    {
-        slaDh2e(DPI+x*fPixSize, -fHeight, DPI/2-fAltAz.Alt(), &az0, &alt0);
-        slaDh2e(DPI+x*fPixSize, +fHeight, DPI/2-fAltAz.Alt(), &az1, &alt1);
-
-        const int z0 = ((int)(360.0/D2PI*(az0+fAltAz.Az()))+360)%360;
-        const int t0 = (int)(360.0/D2PI*alt0);
-
-        fAz0[z0] = kTRUE;
-
-        if (-89<=t0 && t0<=90)
-            fAlt0[90-t0] = kTRUE;
-
-        const int z1 = ((int)(360.0/D2PI*(az1+fAltAz.Az()))+360)%360;
-        const int t1 = (int)(360.0/D2PI*alt1);
-
-        fAz0[z1] = kTRUE;
-
-        if (-89<=t1 && t1<=90)
-            fAlt0[90-t1] = kTRUE;
-    }
-
-    //
-    // scan vertical border
-    //
-    for (int y=-576/2; y<576/2+1; y++)
-    {
-        slaDh2e(DPI-fWidth, y*fPixSize, DPI/2-fAltAz.Alt(), &az0, &alt0);
-        slaDh2e(DPI+fWidth, y*fPixSize, DPI/2-fAltAz.Alt(), &az1, &alt1);
-
-        const int z0 = ((int)(360.0/D2PI*(az0+fAltAz.Az()))+360)%360;
-        const int t0 = (int)(360.0/D2PI*alt0);
-
-        fAz0[z0] = kTRUE;
-
-        if (-89<=t0 && t0<=90)
-            fAlt0[90-t0] = kTRUE;
-
-        const int z1 = ((int)(360.0/D2PI*(az1+fAltAz.Az()))+360)%360;
-        const int t1 = (int)(360.0/D2PI*alt1);
-
-        fAz0[z1] = kTRUE;
-
-        if (-89<=t1 && t1<=90)
-            fAlt0[90-t1] = kTRUE;
-    }
-
-    //
-    // count degrees of azimut
-    //
-    fAzCnt=0;
-    for (int x=0; x<360; x++)
-        if (fAz0[x])
-            fAzCnt++;
-
-    //cout << "fAzCnt: " << setw(3) << fAzCnt << "  " << flush;
-
-    //
-    // calculate min and max of altitude
-    //
-    fAltMin=0;
-    fAltMax=0;
-    for (int y=0; y<180; y++)
-    {
-        if (fAlt0[y])
-            fAltMax = y;
-
-        if (fAlt0[179-y])
-            fAltMin = 179-y;
-    }
-
-    fAltMin -= 90;
-    fAltMax -= 90;
-
-    //
-    // check whether altaz north- or south-pole is in the visible region
-    //
-    byte img[768*576];
-    if (DrawAltAz(0, img, 90, 0))
-    {
-        fAltMax=89;
-        cout << "Alt Az Pole1 Inside!" << endl;
-    }
-    if (DrawAltAz(0, img, -90, 0))
-    {
-        fAltMin=-90;
-        cout << "Alt Az Pole2 Inside!" << endl;
-    }
-
-    //cout << "fAltMin: " << setw(3) << fAltMin << "  ";
-    //cout << "fAltMax: " << setw(3) << fAltMax << endl;
-}
-
-void StarCatalog::CalcRaDecRange()
-{
-    //
-    // calculate range to search in
-    //
-    byte fDec[180];
-
-    for (int h=0; h<180; h++)
-        fDec[h] = kFALSE;
-
-    for (int h=0; h<360; h++)
-        fRa0[h] = kFALSE;
-
-    double ha0, ha1;
-    double de0, de1;
-
-    const double phi   = GetPhi();
-    const double alpha = GetAlpha();
-    //
-    // scan horizontal border
-    //
-    for (int x=-768/2; x<768/2+1; x++)
-    {
-        double dx, dy;
-        slaDh2e(DPI-x*fPixSize, -fHeight, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha0, &de0);
-
-        slaDh2e(DPI-x*fPixSize, +fHeight, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha1, &de1);
-
-        const int h0 = ((int)(360.0/D2PI*(alpha-ha0))+360)%360;
-        const int d0 = (int)(360.0/D2PI*de0);
-
-        fRa0[h0] = kTRUE;
-
-        if (-90<=d0 && d0<=89)
-            fDec[d0+90] = kTRUE;
-
-        const int h1 = ((int)(360.0/D2PI*(alpha-ha1))+360)%360;
-        const int d1 = (int)(360.0/D2PI*de1);
-
-        fRa0[h1] = kTRUE;
-
-        if (-90<=d1 && d1<=89)
-            fDec[d1+90] = kTRUE;
-    }
-
-    //
-    // scan vertical border
-    //
-    for (int y=-576/2; y<576/2+1; y++)
-    {
-        double dx, dy;
-        slaDh2e(DPI-fWidth, -y*fPixSize, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha0, &de0);
-
-        slaDh2e(DPI+fWidth, -y*fPixSize, DPI/2-fAltAz.Alt(), &dx, &dy);
-        slaDh2e(fAltAz.Az()+dx, -dy, phi, &ha1, &de1);
-
-        const int h0 = ((int)(360.0/D2PI*(alpha-ha0))+360)%360;
-        const int d0 = (int)(360.0/D2PI*de0);
-
-        fRa0[h0] = kTRUE;
-
-        if (-90<=d0 && d0<=89)
-            fDec[d0+90] = kTRUE;
-
-        const int h1 = ((int)(360.0/D2PI*(alpha-ha1))+360)%360;
-        const int d1 = (int)(360.0/D2PI*de1);
-
-        fRa0[h1] = kTRUE;
-
-        if (-90<=d1 && d1<=89)
-            fDec[d1+90] = kTRUE;
-    }
-
-    //
-    // count degrees of right ascension
-    //
-    fRaCnt=0;
-    for (int x=0; x<360; x++)
-        if (fRa0[x])
-            fRaCnt++;
-    //cout << "fRaCnt: " << setw(3) << fRaCnt << "  " << flush;
-
-    //
-    // calculate min and max of declination
-    //
-    for (int y=0; y<180; y++)
-    {
-        if (fDec[y])
-            fDecMax = y;
-
-        if (fDec[179-y])
-            fDecMin = 179-y;
-    }
-
-    fDecMin -= 90;
-    fDecMax -= 90;
-
-    //
-    // check whether radec north- or south-pole is in the visible region
-    //
-    byte img[768*576];
-    if (DrawRaDec(0, img, 0, 90))
-    {
-        fDecMax=89;
-        cout << "Ra Dec Pole1 Inside!" << endl;
-    }
-    if (DrawRaDec(0, img, 0, -90))
-    {
-        fDecMin=-90;
-        cout << "Ra Dec Pole1 Inside!" << endl;
-    }
-
-    //cout << "fDecMin: " << setw(3) << fDecMin << "  ";
-    //cout << "fDecMax: " << setw(3) << fDecMax << endl;
-}
-
-void StarCatalog::DrawSCAltAz(byte *img, const int color) const
-{
-    //
-    // ------------ draw az lines ---------------
-    //
-    for (int az=0; az<360; az++)
-    {
-        if (!fAz0[az])
-            continue;
-
-        for (double alt=fAltMin-1; alt<fAltMax+1; alt+=0.006*(fAltMax-fAltMin))
-        {
-            if ((alt>88 && az%5) || alt>89.5)
-                continue;
-
-            DrawAltAz(color, img, alt, az);
-        }
-    }
-
-    //
-    // ------------ draw alt lines ---------------
-    //
-    for (int alt=fAltMin; alt<fAltMax+1; alt++)
-    {
-        for (double az=0; az<360; az+=0.004*fAzCnt)
-        {
-            if (!fAz0[(int)az] && !fAz0[(int)(az+359)%360] && !fAz0[(int)(az+1)%360])
-                continue;
-
-            DrawAltAz(color, img, alt, az);
-        }
-    }
-}
-
-void StarCatalog::DrawSCRaDec(byte *img, const int color) const
-{
-    //
-    // ------------ draw ra lines ---------------
-    //
-    for (int ra=0; ra<360; ra++)
-    {
-        if (!fRa0[ra])
-            continue;
-
-        for (double dec=fDecMin-1; dec<fDecMax+1; dec+=0.005*(fDecMax-fDecMin))
-        {
-            if ((dec>88 && ra%5) || dec>89.5)
-                continue;
-
-            DrawRaDec(color, img, ra, dec, ra==0||ra==90);
-        }
-    }
-
-    //
-    // ------------ draw dec lines ---------------
-    //
-    for (int dec=fDecMin; dec<fDecMax+1; dec++)
-    {
-        for (double ra=0; ra<360; ra+=0.003*fRaCnt)
-        {
-            if (!fRa0[(int)ra])
-                continue;
-
-            DrawRaDec(color, img, ra, dec, dec==89);
-        }
-    }
+    fAstro->SetRaDec(fRaDec.Ra(), fRaDec.Dec());
+    if (!same)
+        Reload();
 }
 
@@ -409,61 +98,6 @@
     memset(cimg, 0, 768*576);
 
-    DrawSCAltAz(cimg, 2<<4);
-    DrawSCRaDec(cimg, 2);
-
     DrawStars(list, cimg);
     DrawCross(img, 768/2, 576/2);
-}
-
-void StarCatalog::GetImg(byte *img, byte *cimg, const double utc,
-                         const RaDec &radec)
-{
-    MStarList list;
-    GetStars(list, utc, radec);
-    GetImg(img, cimg, list);
-    /*
-     // memset(img,  0, 768*576);
-     SetMjd(utc);
-     //fAlpha = sla.GetAlpha();
-     SetRaDec(radec);
-     //CalcImg(cimg);
-     */
-}
-
-void StarCatalog::GetImg(byte *img, byte *cimg, const double utc,
-                         const AltAz &altaz)
-{
-    MStarList list;
-    GetStars(list, utc, altaz);
-    GetImg(img, cimg, list);
-    /*
-     // memset(img,  0, 768*576);
-
-     SetMjd(utc);
-     //fAlpha = sla.GetAlpha();
-     SetAltAz(altaz);
-
-     CalcRaDecRange();
-
-     //CalcImg(img);
-     */
-
-}
-
-void StarCatalog::GetStars(MStarList &list, const double utc, const RaDec &radec)
-{
-    SetMjd(utc);
-    SetRaDec(radec);
-
-    CalcStars(list);
-}
-
-void StarCatalog::GetStars(MStarList &list, const double utc, const AltAz &altaz)
-{
-    SetMjd(utc);
-    SetAltAz(altaz);
-
-    CalcRaDecRange();
-    CalcStars(list);
 }
 
@@ -489,143 +123,9 @@
 }
 
-Bool_t StarCatalog::DrawAltAz(const int color, byte *img, double alt, double az, int size) const
-{
-    //
-    // alt/az[deg] -> alt/az[rad]
-    //
-    alt *= D2PI/360.0;
-    az  *= D2PI/360.0;
-
-    //
-    // alt/az[rad] -> alt/az[pix]
-    //
-    double dx, dy;
-    slaDe2h(az-fAltAz.Az(), -alt, DPI/2-fAltAz.Alt(), &dx, &dy);
-
-    //
-    // Align alt/az[pix]
-    //
-    const int xx = (int)(((dx-DPI)*fCosAngle - dy*fSinAngle + fWidth)/fPixSize);
-    const int yy = (int)(((dx-DPI)*fSinAngle + dy*fCosAngle + fHeight)/fPixSize);
-    //const int xx = 767-(int)((fWidth-dx+DPI)/fPixSize);
-    //const int yy =     (int)((fHeight+dy)/fPixSize);
-
-    //
-    // Range Check
-    //
-    if (!(0<=xx && xx<768 && 0<=yy && yy<576))
-        return kFALSE;
-
-    //
-    // Draw
-    //
-    DrawCircle(color, img, xx, yy, size);
-
-    return kTRUE;
-}
-
-Bool_t StarCatalog::Draw(const int color, byte *img, const AltAz &altaz)
-{
-    return DrawAltAz(color, img, altaz.Alt(), altaz.Az());
-}
-
-/*
-Bool_t StarCatalog::Draw(const int color, byte *img, const SaoFile *sao)
-{
-    if (sao->MagV() > fLimitMag)
-        return kFALSE;
-
-    //
-    // ---- mean to observed ---
-    //
-    AltAz altaz=CalcAltAz(sao->GetRaDec()) * 360.0/D2PI;
-
-    const int mag = (10 - (sao->MagV()>1 ? (int)sao->MagV() : 1))/2;
-
-    //
-    // ---- imaging -----
-    //
-    return DrawAltAz(color, img, altaz.Alt(), altaz.Az(), mag);
-}
-*/
-
-Bool_t StarCatalog::DrawRaDec(const int color, byte *img, double ra, double dec, int size) const
-{
-    //
-    // radec[deg] -> radec[rad]
-    //
-    ra  *= D2PI/360.0;
-    dec *= D2PI/360.0;
-
-    //
-    // radec[rad] -> hadec[rad]
-    //
-    const double ha = GetAlpha()-ra;
-
-    //
-    // hadec[rad] -> altaz[rad]
-    //
-    double alt, az;
-    slaDe2h(ha, dec, GetPhi(), &az, &alt);
-
-    //
-    // altaz[rad] -> altaz[deg]
-    //
-    alt *= 360.0/D2PI;
-    az  *= 360.0/D2PI;
-
-    return DrawAltAz(color, img, alt, az, size);
-}
-
-Bool_t StarCatalog::Draw(const int color, byte *img, const RaDec &radec)
-{
-    return DrawRaDec(color, img, radec.Ra(), radec.Dec());
-}
-/*
-void StarCatalog::CalcImg(byte *img)
-{
-
-    //
-    // --------- search for stars in catalog ----------
-    //
-    int count   = 0;
-    int deleted = 0;
-
-    int idx     = 0;
-
-    while (fSrt[idx].dec<fDecMin)
-        idx++;
-
-    idx--;
-    while (++idx<fEntries && fSrt[idx].dec<fDecMax+1)
-    {
-        const int ra = fSrt[idx].ra;
-
-        if (!fRa0[ra])
-            continue;
-
-        int nr = fSrt[idx].nr;
-        do
-        {
-            //
-            // Get entry from catalog
-            //
-            fSao->GetEntry(nr++);
-
-            //
-            // Try to draw star into the image
-            //  white = 0xff
-            //
-            if (!Draw(0x0f, img, fSao))
-                deleted++;
-
-            count++;
-        }
-        while ((int)(360.0/D2PI*fSao->Ra())==ra);
-    }
-
-    cout << " " << count << "-" << deleted << "=" << count-deleted << " " << flush;
-}
-*/
+void StarCatalog::PaintImg(unsigned char *buf, int w, int h)
+{
+    fAstro->PaintImg(buf, w, h);
+}
+
 void StarCatalog::DrawStars(MStarList &list, byte *img)
 {
@@ -637,6 +137,5 @@
         const int mag = (10 - (star->GetMag()>1 ? (int)star->GetMag() : 1))/2;
 
-        Double_t color = 0x0f;
-
+        Double_t color = 0xf0; //0x0f;
         DrawCircle(color, img, (int)star->GetX(), (int)star->GetY(), mag);
     }
@@ -645,80 +144,68 @@
 void StarCatalog::CalcStars(MStarList &list) const
 {
-    //
-    // --------- search for stars in catalog ----------
-    //
-    if (fEntries==0)
-        return;
-
-    int count   = 0;
-    int deleted = 0;
-
-    int idx     = 0;
-
-    while (fSrt[idx].dec<fDecMin)
-        idx++;
-
-    idx--;
-    while (++idx<fEntries && fSrt[idx].dec<fDecMax+1)
+    // Align stars into telescope system
+    // (Move the telescope to pointing position)
+    TRotation align;
+    align.RotateZ(-fAltAz.Az());
+    align.RotateY(-(TMath::Pi()/2-fAltAz.Alt()));
+    align.RotateZ(TMath::Pi()/2);
+
+    // For an apropriate unit conversion to pixels
+    const Double_t scale = TMath::RadToDeg()*sqrt(768*768 + 576*576)/(fAstro->GetRadiusFOV()*2);
+
+    // Get List of stars from catalog
+    TIter Next(fAstro->GetList());
+    TVector3 *star=0;
+
+    const Double_t limmag = pow(10, -fLimitMag/2.5);
+
+    while ((star=(TVector3*)Next()))
     {
-        const int ra = fSrt[idx].ra;
-
-        if (!fRa0[ra])
+        // Check for limiting magnitude
+        const Double_t mag = star->Mag();
+        if (mag < limmag)
             continue;
 
-        int nr = fSrt[idx].nr;
-        do
-        {
-            //
-            // Get entry from catalog
-            //
-            fSao->GetEntry(nr++);
-
-            if (fSao->MagV() > fLimitMag)
-                continue;
-
-            //
-            // ---- mean to observed ---
-            //
-            AltAz altaz=CalcAltAz(fSao->GetRaDec());
-
-            //
-            // alt/az[rad] -> alt/az[pix]
-            //
-            double dx, dy;
-            slaDe2h(altaz.Az()-fAltAz.Az(), -altaz.Alt(),
-                    DPI/2-fAltAz.Alt(), &dx, &dy);
-
-            //
-            // Align and rotate alt/az[pix]
-            //
-            float xx = ((dx-DPI)*fCosAngle - dy*fSinAngle + fWidth)/fPixSize;
-            float yy = ((dx-DPI)*fSinAngle + dy*fCosAngle + fHeight)/fPixSize;
-
-            //
-            // Range Check, add stars to the list
-            //
-            if (!(0<=xx && xx<768 && 0<=yy && yy<576))
-            {
-                deleted++;
-                continue;
-            }
-
-            list.Add(xx, yy, fSao->MagV());
-            count++;
-        }
-        while ((int)(360.0/D2PI*fSao->Ra())==ra);
+        // Get star position and do an apropiate
+        // conversion to local coordinates
+        const RaDec rd(star->Phi(), TMath::Pi()/2-star->Theta());
+        const ZdAz  za(CalcZdAz(rd));
+
+        // Virtually move telescope to pointing position
+        TVector3 loc;
+        loc.SetMagThetaPhi(1, za.Zd(), za.Az());
+        loc *= align;
+
+        // Sanity check
+        if (loc(2)<0)
+            continue;
+
+        // Stretch such, that the Z-component is alwas the same. Now
+        // X and Y contains the intersection point between the star-light
+        // and the plain of a virtual plain screen (ccd...)
+        loc *= 1./loc(2);
+
+        // Do an apropriate unit conversion to pixels
+        loc *= scale;
+
+        // if (loc.Mod2()>fRadiusFOV*fRadiusFOV)
+        //     continue;
+
+        // Rotate by the rotation angle of the video camera
+        Float_t xx = loc.X()*fCosAngle - loc.Y()*fSinAngle;
+        Float_t yy = loc.X()*fSinAngle + loc.Y()*fCosAngle;
+
+        // Store pixel coordinates of star in list
+        list.Add(xx+768/2, yy+576/2, -2.5*log10(mag));
     }
-
-    cout << "Showing " << count+deleted << "-" << deleted << "=" << count << " stars." << endl;
 }
 
 AltAz StarCatalog::CalcAltAzFromPix(Double_t pixx, Double_t pixy) const
 {
-    pixx *= fPixSize;
-    pixy *= fPixSize;
-
-    const double dx =  (pixx-fWidth)*fCosAngle + (pixy-fHeight)*fSinAngle;
-    const double dy = -(pixx-fWidth)*fSinAngle + (pixy-fHeight)*fCosAngle;
+    double dx =  (pixx-576/2)*fCosAngle + (pixy-768/2)*fSinAngle;
+    double dy = -(pixx-576/2)*fSinAngle + (pixy-768/2)*fCosAngle;
+
+    dx *= fPixSize;
+    dy *= fPixSize;
 
     //const double dx = (pixx-768.0)*fPixSize + fWidth+DPI;
Index: trunk/MagicSoft/Cosy/catalog/StarCatalog.h
===================================================================
--- trunk/MagicSoft/Cosy/catalog/StarCatalog.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/catalog/StarCatalog.h	(revision 4076)
@@ -4,4 +4,7 @@
 #ifndef ROOT_TROOT
 #include <TROOT.h>
+#endif
+#ifndef ROOT_GuiTypes
+#include <GuiTypes.h>
 #endif
 #ifndef SAOFILE_H
@@ -17,15 +20,12 @@
 
 class MStarList;
+class MAstroCatalog;
 
 class StarCatalog : public SlaStars
 {
 private:
-    SaoFile *fSao;
-    sort_t  *fSrt;
-    int      fEntries;
+    MAstroCatalog *fAstro;
 
     double   fPixSize;  // [rad/pix] size of one pixel
-    double   fWidth;    // size of display
-    double   fHeight;   //
     double   fSinAngle;
     double   fCosAngle;
@@ -34,41 +34,11 @@
 
     AltAz    fAltAz;    // [rad]
-    byte     fAz0[360];
-    int      fAltMin;
-    int      fAltMax;
-    int      fAzCnt;
-
     RaDec    fRaDec;    // [rad]
-    byte     fRa0[360];
-    int      fRaCnt;
-    int      fDecMin;
-    int      fDecMax;
 
     static void DrawCross(byte *img, const int x, const int y);
     static void DrawCircle(int color, byte *img, int xx, int yy, int size);
 
-    Bool_t DrawAltAz(const int color, byte *img, double alt, double az,  int size=0) const;
-    Bool_t DrawRaDec(const int color, byte *img, double ra,  double dec, int size=0) const;
-
-    Bool_t Draw(const int color, byte *img, const AltAz &altaz);
-    Bool_t Draw(const int color, byte *img, const RaDec &radec);
-
-    //Bool_t Draw(const int color, byte *img, const SaoFile *sao);
-    //void   CalcImg(byte *);
-
-    void   CalcStars(MStarList &list) const;
-
-    static void DrawStars(MStarList &list, byte *img);
-
     void   SetRaDec(const RaDec &radec);
     void   SetAltAz(const AltAz &altaz);
-    void   DrawSCAltAz(byte *img, const int color) const;
-    void   DrawSCRaDec(byte *img, const int color) const;
-  
-    void   CalcRaDecRange();
-    void   CalcAltAzRange();
-
-//    RaDec  AltAz2RaDec(const AltAz &altaz) const;
-//    AltAz  RaDec2AltAz(const RaDec &radec, const RaDec &rdpm) const;
 
 public:
@@ -77,9 +47,5 @@
 
     void GetImg(byte *img, byte *cimg, MStarList &list) const;
-    void GetImg(byte *img, byte *cimg, const double utc, const RaDec &radec);
-    void GetImg(byte *img, byte *cimg, const double utc, const AltAz &altaz);
-
-    void GetStars(MStarList &list, const double utc, const RaDec &radec);
-    void GetStars(MStarList &list, const double utc, const AltAz &altaz);
+    void PaintImg(unsigned char *buf, int w, int h);
 
     const AltAz GetAltAz() const { return fAltAz*kRad2Deg; }
@@ -88,6 +54,7 @@
 
     void  SetPixSize(const double pixsize);
-    void  SetLimitMag(const float mag) { fLimitMag = mag; }
+    void  SetLimitMag(const float mag);
     void  SetRotationAngle(const float angle) { fSinAngle = sin(angle/kRad2Deg); fCosAngle = cos(angle/kRad2Deg); }
+    void  Reload();
 
     double GetPixSize() const;
@@ -95,4 +62,14 @@
     AltAz CalcAltAzFromPix(Double_t pixx, Double_t pixy) const;
 
+    virtual void SetMjd(double mjd);
+
+    void SetPointing(double mjd, const RaDec &radec)
+    {
+        SetMjd(mjd); SetRaDec(radec);
+    }
+
+    void   CalcStars(MStarList &list) const;
+    static void DrawStars(MStarList &list, byte *img);
+
     ClassDef(StarCatalog, 0)
 };
Index: trunk/MagicSoft/Cosy/cosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/cosy.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/cosy.cc	(revision 4076)
@@ -10,10 +10,8 @@
 #include "MLogManip.h"
 
-#include "Camera.h"
-#include "PngReader.h"
 #include "MStarguider.h"
 
-//#define EXPERT
-//#define HAVE_CAMERA
+#define EXPERT
+#define HAVE_CAMERA
 
 #define clog(txt) \
@@ -36,24 +34,26 @@
     gLog << endl;
 
+    Int_t channel = 0;
+    for (int i=0; i<argc; i++)
+    {
+        TString arg(argv[i]);
+        if (arg=="-1")
+            channel = 1;
+        if (arg=="-0")
+            channel = 0;
+    }
+
     //
     // this must move to MGCosy !!!!
     //
-    MTime time;
-    TString name;
-    while (1)
-    {
-        time.Now();
-        name = Form("log/cosy_%s.log", (const char*)time.GetFileName());
-        cout << "Test: " << time.GetFileName() << " " << name << endl;
-        if (gSystem->AccessPathName(name, kFileExists))
-            break;
-    }
-
+    const TString name = MCosy::GetFileName("log/cosy_%s.log");
     cout << "Open Logfile: " << name << endl;
 
     MLog *l = new MLog(name, kTRUE);
     MLog &lout = *l;
+    lout.SetNoColors();
 
-    clog("Starting Cosy at " << time << " ...");
+    MTime now(-1);
+    clog("Starting Cosy at " << now << " ...");
 
     //
@@ -98,7 +98,5 @@
     clog("- Starting Camera.");
 #ifdef HAVE_CAMERA
-    MStarguider *client=new MStarguider(MObservatory::kMagic1);
-    Camera *cam = new Camera(*client);
-    cam->Loop(0);
+    MStarguider *client=new MStarguider(MObservatory::kMagic1, channel);
 
     cosy->SetStarguider(client);
@@ -115,6 +113,4 @@
 
     clog("- Stopping starg.");
-    cam->ExitLoop();
-    delete cam;
     delete client;
 #endif
@@ -122,11 +118,11 @@
     cosy->Stop();
 
-    time.Now();
-    clog(time << ": MCosy stopped.");
+    now.Now();
+    clog(now << ": MCosy stopped.");
 
     delete cosy;
 
-    time.Now();
-    clog("Terminating cosy at " << time);
+    now.Now();
+    clog("Terminating cosy at " << now);
 
     delete l;
Index: trunk/MagicSoft/Cosy/devdrv/macs.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 4076)
@@ -118,4 +118,6 @@
     void HandleError();
 
+    Double_t GetPosTime() const { return fPosTime; }
+
     ClassDef(Macs, 0)
 };
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 4076)
@@ -14,5 +14,5 @@
 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)
+    fTurn(0), fLabel(NULL), fPosHasChanged(false), fReport(NULL)
 {
 }
@@ -183,4 +183,11 @@
     fTime.Set(*tv);
     fPosHasChanged = true;
+
+    if (fReport)
+    {
+        fReport->Lock();
+        *fReport << "SE-REPORT " << (int)GetId() << " " << fTime << " PDO0 " << pos << " " << GetNodeName() << endl;
+        fReport->UnLock();
+    }
 }
 
@@ -201,4 +208,11 @@
 
     flag=flag;
+
+    if (fReport)
+    {
+        fReport->Lock();
+        *fReport << "SE-REPORT " << (int)GetId() << " " << fTime << " PDO1 " << pos << " " << (int)flag << " " << GetNodeName() << endl;
+        fReport->UnLock();
+    }
 }
 
@@ -235,4 +249,11 @@
     fTime.Set(*tv);
     fPosHasChanged=true;
+
+    if (fReport)
+    {
+        fReport->Lock();
+        *fReport << "SE-REPORT " << (int)GetId() << " " << fTime << " PDO2 " << pos << " " << fVel << " " << fAcc << " " << GetNodeName() << endl;
+        fReport->UnLock();
+    }
 }
 
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 4076)
@@ -25,4 +25,5 @@
 
     MTime fTime;
+    MLog *fReport;
 
     void HandlePDOType0(BYTE_t *data, timeval_t *tv);
@@ -63,4 +64,6 @@
     void ResetPosHasChanged() { fPosHasChanged = false; }
 
+    void SetReport(MLog *log) { fReport = log; }
+
     ClassDef(ShaftEncoder, 0)
 };
Index: trunk/MagicSoft/Cosy/gui/MGAccuracy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 4076)
@@ -15,7 +15,9 @@
 #include <TList.h>
 #include <TGaxis.h>
+#include <TGraph.h>
 #include <TCanvas.h>
 
 #include "coord.h"
+#include "MTime.h"
 
 ClassImp(MGAccuracy);
@@ -28,5 +30,5 @@
     TText text;
     text.SetTextAlign(22);  // centered, centered (s.TAttText)
-    text.DrawText(-80*2, 132.5*2, "Tracking Error [']");
+    text.DrawText(-80*2, 132.5*2, "Ctrl Deviation [min]");
 
 
@@ -75,66 +77,4 @@
     axe->SetBit(kCanDelete);
     axe->Draw();
-
-    //
-    // FIXME? Use TAxis?
-    //
-/*
-    TLine line;
-    line.SetLineColor(13);
-    line.SetLineStyle(3);  // dotted  (s. TAttLine)
-    line.DrawLine(-30, -65, -30,  65);
-    line.DrawLine(-65, -30,  65, -30);
-    line.DrawLine( 30, -65,  30,  65);
-    line.DrawLine(-65,  30,  65,  30);
-
-    line.DrawLine(-15, -65, -15,  65);
-    line.DrawLine(-65, -15,  65, -15);
-    line.DrawLine( 15, -65,  15,  65);
-    line.DrawLine(-65,  15,  65,  15);
-
-    line.DrawLine(-45, -65, -45,  65);
-    line.DrawLine(-65, -45,  65, -45);
-    line.DrawLine( 45, -65,  45,  65);
-    line.DrawLine(-65,  45,  65,  45);
-
-    line.SetLineColor(12);
-    line.SetLineStyle(2);  // dashed  (s. TAttLine)
-    line.DrawLine(-60, -65, -60,  65);
-    line.DrawLine(-65, -60,  65, -60);
-    line.DrawLine( 60, -65,  60,  65);
-    line.DrawLine(-65,  60,  65,  60);
-
-    line.SetLineColor(1);  // black
-    line.SetLineStyle(1);  // solid  (s. TAttLine)
-    line.DrawLine(-65,   0, 65,  0);
-    line.DrawLine(  0, -65,  0, 65);
-
-    line.DrawLine(-1,  60, 1,  60);
-    line.DrawLine(-1, -60, 1, -60);
-    line.DrawLine(-1,  30, 1,  30);
-    line.DrawLine(-1, -30, 1, -30);
-
-    line.DrawLine( 60, -1,  60, 1);
-    line.DrawLine(-60, -1, -60, 1);
-    line.DrawLine( 30, -1,  30, 1);
-    line.DrawLine(-30, -1, -30, 1);
-
-    TText text;
-    text.SetTextAlign(22);  // centered, centered (s.TAttText)
-    text.DrawText(60, 5, "dAz[\xb0]");
-    text.DrawText(0, 70, "dZd[\xb0]");
-
-    text.SetTextAlign(23);  // centered, centered (s.TAttText)
-    text.DrawText(-60, -2, "-1'");
-    text.DrawText( 60, -2, "1'");
-    text.DrawText(-30, -2, "-30\"");
-    text.DrawText( 30, -2, "30\"");
-
-    text.SetTextAlign(32);  // centered, centered (s.TAttText)
-    text.DrawText(-2, -60, "-1'");
-    text.DrawText(-2,  60, "1'");
-    text.DrawText(-2, -30, "-30\"");
-    text.DrawText(-2,  30, "30\"");
-    */
 }
 
@@ -183,4 +123,17 @@
 : MGEmbeddedCanvas("Accuracy", p, w, 300)
 {
+    // FIXME: Overload MapWindow in newer Root versions to remove
+    //        the contents of the graph!
+    fGraph = new TGraph;
+    fGraph->SetPoint(0, 0, 0);
+    fGraph->SetLineColor(kBlue);
+    fGraph->SetMarkerColor(kBlue);
+    fGraph->SetMarkerStyle(kFullDotMedium);
+    fGraph->Draw("LP");
+    fList->Add(fGraph);
+    //fGraph->SetNameTitle("AccVsT", "Accuracy vs Min of Time");
+    //fGraph->Draw("APL");
+    //fGraph->SetMarkerSize(2);
+
     DrawCoordinateSystem();
 
@@ -192,4 +145,7 @@
 
     SetNoContextMenu();
+
+    MTime t(-1);
+    fTime = t.GetAxisTime();
 }
 
@@ -199,38 +155,13 @@
 }
 
-void MGAccuracy::UpdateText(Float_t pzd, Float_t azd, Float_t aaz)
-{
-    const Float_t d2r = TMath::Pi()/180.;
-
-    pzd *= d2r;
-    azd *= d2r;
-    aaz *= d2r;
-
-    const double el = TMath::Pi()/2-pzd;
-
-    const double dphi2 = aaz/2.;
-    const double cos2  = cos(dphi2)*cos(dphi2);
-    const double sin2  = sin(dphi2)*sin(dphi2);
-    const double d     = cos(azd)*cos2 - cos(2*el)*sin2;
-
-    //
-    // Original:
-    //   cos(Zd1)*cos(Zd2)+sin(Zd1)*sin(Zd2)*cos(dAz)
-    //
-    // Correct:
-    //   const double d = cos(azd)*cos2 - cos(el1+el2)*sin2;
-    //
-    // Estimated:
-    //   const double d = cos(azd)*cos2 - cos(2*el)*sin2;
-    //
-
-    double dist = acos(d);
-
-    dist *= 3600./d2r; // [min]
+// dist [deg]
+void MGAccuracy::UpdateText(Float_t dist)
+{
+    dist *= 3600.; // [sec]
 
     int rs = (int)floor(fmod(dist, 60.));
 
-    dist /= 60.;
-    int rm = (int)dist;//floor(fmod(dist, 60.));
+    dist /= 60.;   // [min]
+    int rm = (int)dist;
 
     char txt[100];
@@ -239,5 +170,5 @@
     fTxt->SetText(fTxt->GetX(), fTxt->GetY(), txt);
 
-    fBar->SetX2(dist*60);
+    fBar->SetY2(dist*60); // [sec]
     if (dist*16384<1*360*60)
         fBar->SetLineColor(kGreen);
@@ -247,8 +178,114 @@
         else
             fBar->SetLineColor(kRed);
+
+    SetModified();
+}
+
+// dist [deg]
+void MGAccuracy::UpdateGraph(Float_t dist)
+{
+    MTime t(-1);
+    const Double_t dtime = t.GetAxisTime()-fTime; // range [-0.5h, 0h]
+
+    dist *= 60; // min
+
+    static int odist = -1;
+    if (odist==(int)(dist*10*60) && dtime<10)
+        return;
+
+    odist = (int)(dist*10*60);
+
+    fGraph->SetPoint(fGraph->GetN(), dtime, dist*60);
+
+    const Double_t ntime = dtime;
+    for (int i=0; i<fGraph->GetN(); i++)
+    {
+        Double_t x, y;
+        fGraph->GetPoint(i, x,       y);
+        fGraph->SetPoint(i, x-ntime, y);
+        //cout << i << ":  " << x-ntime << " / " << y << endl;
+    }
+    while (fGraph->GetN()>0)
+    {
+        Double_t x, y;
+        fGraph->GetPoint(0, x, y);
+
+        if (x==-ntime && y==0)
+        {
+            fGraph->RemovePoint(0);
+            continue;
+        }
+
+        if (x>-4.75*60)
+            break;
+
+        fGraph->RemovePoint(0);
+    }
+
+    fTime = t.GetAxisTime();
+
+    SetModified();
+
+    //cout << "N1 == " << fGraph->GetN() << endl;
+
+    //fGraph->GetHistogram()->SetXTitle("Time");
+    //fGraph->GetHistogram()->SetYTitle("\\Delta [arcmin]");
+    //fGraph->GetHistogram()->GetXaxis()->SetTimeFormat("%M %F1995-01-01 00:00:00");
+    //fGraph->GetHistogram()->GetXaxis()->SetTimeDisplay(1);
+    //fGraph->GetHistogram()->GetXaxis()->SetLabelSize(0.033);
+}
+
+void MGAccuracy::Update(Float_t pzd, Float_t azd, Float_t aaz)
+{
+    const Float_t d2r = TMath::Pi()/180.;
+
+    pzd *= d2r;
+    azd *= d2r;
+    aaz *= d2r;
+
+    const double el = TMath::Pi()/2-pzd;
+
+    const double dphi2 = aaz/2.;
+    const double cos2  = cos(dphi2)*cos(dphi2);
+    const double sin2  = sin(dphi2)*sin(dphi2);
+    const double d     = cos(azd)*cos2 - cos(2*el)*sin2;
+
+    //
+    // Original:
+    //   cos(Zd1)*cos(Zd2)+sin(Zd1)*sin(Zd2)*cos(dAz)
+    //
+    // Correct:
+    //   const double d = cos(azd)*cos2 - cos(el1+el2)*sin2;
+    //
+    // Estimated:
+    //   const double d = cos(azd)*cos2 - cos(2*el)*sin2;
+    //
+
+    double dist = acos(d)*TMath::RadToDeg();
+
+    UpdateText(dist);
+    UpdateGraph(dist);
 }
 
 void MGAccuracy::UpdateCross(Float_t x, Float_t y)
 {
+    //
+    // calculate actual time for planet positions
+    // acc [deg]
+    //
+    // x["], y["]
+    //
+    static int X = ~0;
+    static int Y = ~0;
+
+    int pixx = (int)(x/fPix);  // [pix]
+    int pixy = (int)(y/fPix);  // [pix]
+
+    if (X==pixx && Y==pixy)
+        return;
+
+    X = pixx;
+    Y = pixy;
+
     fLin1->SetX1(x-5.);
     fLin1->SetX2(x+5.);
@@ -262,31 +299,13 @@
     fLin2->SetY1(y+5.);
     fLin2->SetY2(y-5.);
+
+    SetModified();
 }
 
 void MGAccuracy::Update(ZdAz &pos, ZdAz &acc)
 {
-    //
-    // calculate actual time for planet positions
-    // acc [deg]
-    //
-    static int X = ~0;
-    static int Y = ~0;
-
-    float x = acc.Az()*3600.; // ["]
-    float y = acc.Zd()*3600.; // ["]
-
-    int pixx = (int)(x/fPix);  // [pix]
-    int pixy = (int)(y/fPix);  // [pix]
-
-    if (X==pixx && Y==pixy)
-        return;
-
-    X = pixx;
-    Y = pixy;
-
-    UpdateCross(x, y);
-    UpdateText(pos.Zd(), acc.Zd(), acc.Az());
-
-    SetModified();
+    UpdateCross(acc.Az()*3600., acc.Zd()*3600.);
+    Update(pos.Zd(), acc.Zd(), acc.Az());
+
     UpdateCanvas();
 }
Index: trunk/MagicSoft/Cosy/gui/MGAccuracy.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGAccuracy.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGAccuracy.h	(revision 4076)
@@ -8,8 +8,9 @@
 //   Version: V1.0 (1-8-2000)
 
-#ifndef MGEMBEDDEDCANVAS_H
+#ifndef COSY_MGEmbeddedCanvas
 #include "MGEmbeddedCanvas.h"
 #endif
 
+class TGraph;
 class TLine;
 class TText;
@@ -26,4 +27,8 @@
     TLine  *fBar;
 
+    TGraph *fGraph;
+
+    Double_t fTime;
+
     void DrawCoordinateSystem();
 
@@ -32,6 +37,8 @@
     void InitBar();
 
-    void UpdateText(Float_t zd, Float_t x, Float_t y);
     void UpdateCross(Float_t x, Float_t y);
+    void UpdateText(Float_t acc);
+    void UpdateGraph(Float_t acc);
+    void Update(Float_t zd, Float_t x, Float_t y);
 
 public:
Index: trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.h	(revision 4076)
@@ -1,4 +1,4 @@
-#ifndef MGEMBEDDEDCANVAS_H
-#define MGEMBEDDEDCANVAS_H
+#ifndef COSY_MGEmbeddedCanvas
+#define COSY_MGEmbeddedCanvas
 
 //
Index: trunk/MagicSoft/Cosy/gui/MGImage.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGImage.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGImage.cc	(revision 4076)
@@ -7,4 +7,15 @@
 // x11/src/GX11Gui.cxx
 //
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// MGImage
+//
+// If sync-mode is enabled the Redraw function is secured by a mutex (ignore
+// error messages about it comming from root) This has the advantage that
+// if you use a timer for screen update reading and writing the image is
+// synchronized. In this way you don't get flickering half images.
+//
+//////////////////////////////////////////////////////////////////////////////
 #include "MGImage.h"
 
@@ -17,14 +28,4 @@
 
 using namespace std;
-/*
-class MyX11 : public TGX11
-{
-public:
-    Display *GetDisplay() { return fDisplay; }
-    Drawable GetRootWin() { return fRootWin; }
-    Drawable GetVisRootWin() { return fVisRootWin; }
-    Int_t    GetDepth() { return fDepth; }
-};
-*/
 
 MGImage::MGImage(const TGWindow* p, UInt_t w, UInt_t h, UInt_t options, ULong_t back)
@@ -40,10 +41,9 @@
     fMuxPixmap = new TMutex;
 
-    Resize(w, h);
+    Resize(GetWidth(), GetHeight());
 
     //
     // create empty pixmap
     //
-    fPixmap = gVirtualX->CreatePixmap(fId, fWidth, fHeight);
     fDefGC  = gVirtualX->CreateGC(fId, 0);
     fImage  = (XImage*)gVirtualX->CreateImage(fWidth, fHeight);
@@ -54,9 +54,9 @@
 MGImage::~MGImage()
 {
-    fMuxPixmap->Lock();
+    if (fMuxPixmap->Lock()==13)
+        cout << "MGImage::~MGImage - mutex is already locked by this thread" << endl;
 
     cout << "Deleting MGImage..." << endl;
 
-    gVirtualX->DeletePixmap(fPixmap);
     gVirtualX->DeleteGC(fDefGC);
     gVirtualX->DeleteImage((Drawable_t)fImage);
@@ -69,13 +69,23 @@
 void MGImage::DoRedraw()
 {
-    fMuxPixmap->Lock();
-
-    if (TestBit(kNeedRedraw))
-    {
-        gVirtualX->PutImage(fId, fDefGC, (Drawable_t)fImage, 0, 0, 0, 0, fWidth, fHeight);
+    if (TestBit(kSyncMode))
+        while (fMuxPixmap->Lock()==13)
+            usleep(1);
+
+    //    gVirtualX->DrawLine(fId, fDefGC, 0, 0, fWidth+2, 0);
+    //    gVirtualX->DrawLine(fId, fDefGC, 0, 0, 0, fHeight+2);
+    //    gVirtualX->DrawLine(fId, fDefGC, fWidth+2, 0,  fWidth+2, fHeight+2);
+    //    gVirtualX->DrawLine(fId, fDefGC, 0, fHeight+2, fWidth+2, fHeight+2);
+
+    //    if (TestBit(kNeedRedraw))
+    {
+        gVirtualX->PutImage(fId, fDefGC, (Drawable_t)fImage, 0, 0, 0, 0,
+                            fWidth, fHeight);
         ResetBit(kNeedRedraw);
     }
 
-    fMuxPixmap->UnLock();
+    if (TestBit(kSyncMode))
+        if (fMuxPixmap->UnLock()==13)
+            cout << "MGImage::DoRedraw - tried to unlock mutex locked by other thread." << endl;
 }
 
@@ -109,6 +119,15 @@
 void MGImage::DrawImg(const byte *buffer)
 {
-    if (fMuxPixmap->TryLock())
-        return;
+    if (TestBit(kSyncMode))
+        while (fMuxPixmap->Lock()==13)
+            usleep(1);
+    else
+    {
+        const Int_t rc = fMuxPixmap->Lock();
+        if (rc==13)
+            cout << "MGImage::DrawImg - mutex is already locked by this thread" << endl;
+        if (rc)
+            return;
+    }
 
     switch (gVirtualX->GetDepth())
@@ -129,5 +148,6 @@
     SetBit(kNeedRedraw);
 
-    fMuxPixmap->UnLock();
+    if (fMuxPixmap->UnLock()==13)
+        cout << "MGImage::DrawImage - tried to unlock mutex locked by other thread." << endl;
 }
 
@@ -143,6 +163,6 @@
         {    
             //      00000011   00001100        00110000
-            *d++ = (*s2&0x3) | (*s2&0xb)<<3 | (*s2&0x30)<<7;
-            s1++;
+            //*d++ = (*s2&0x3) | (*s2&0xb)<<3 | (*s2&0x30)<<7;
+            *d++ = (*s2&0x3)<<3 | (*s2&0xb)<<6 | (*s2&0x30)<<10;
         }
         else
@@ -150,6 +170,7 @@
             //      11111100     11111000        11111100
             *d++ = (*s1&0xfc) | (*s1&0xf8)<<5 | (*s1&0xfc)<<11;
-            s2++;
-        }
+        }
+        s1++;
+        s2++;
     }
 }
@@ -181,6 +202,15 @@
 void MGImage::DrawColImg(const byte *gbuf, const byte *cbuf)
 {
-    if (fMuxPixmap->TryLock())
-        return;
+    if (TestBit(kSyncMode))
+        while (fMuxPixmap->Lock()==13)
+            usleep(1);
+    else
+    {
+        const Int_t rc = fMuxPixmap->Lock();
+        if (rc==13)
+            cout << "MGImage::DrawColImg - mutex is already locked by this thread" << endl;
+        if (rc)
+            return;
+    }
 
     // FROM libAfterImage:
@@ -190,5 +220,5 @@
     //#define ALPHA_SOLID            	0xFF
     // * Lowermost 8 bits - Blue channel
-    // * bits 8 to 15     - Green channel
+    // * bits  8 to 15    - Green channel
     // * bits 16 to 23    - Red channel
     // * bits 24 to 31    - Alpha channel
@@ -211,4 +241,5 @@
     SetBit(kNeedRedraw);
 
-    fMuxPixmap->UnLock();
-}
+    if (fMuxPixmap->UnLock()==13)
+        cout << "MGImage::DrawColImage - tried to unlock mutex locked by other thread." << endl;
+}
Index: trunk/MagicSoft/Cosy/gui/MGImage.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGImage.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGImage.h	(revision 4076)
@@ -24,5 +24,5 @@
 
     GContext_t fDefGC;
-    Pixmap_t   fPixmap;
+    //Pixmap_t   fPixmap;
 
     UInt_t fWidth;
@@ -31,5 +31,9 @@
     TMutex *fMuxPixmap; //! test
 
-    enum { kNeedRedraw = BIT(17) };
+    enum
+    {
+        kNeedRedraw = BIT(17),
+        kSyncMode   = BIT(18)
+    };
 
     void DrawImg16(unsigned short *d, char *s, char *e);
@@ -47,4 +51,7 @@
     void DrawColImg(const byte *gbuf, const byte *cbuf);
 
+    void EnableSyncMode()  { SetBit(kSyncMode); }
+    void DisableSyncMode() { ResetBit(kSyncMode); }
+
     ClassDef(MGImage, 0)
 };
Index: trunk/MagicSoft/Cosy/gui/MGPngReader.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGPngReader.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGPngReader.cc	(revision 4076)
@@ -347,5 +347,5 @@
     const Double_t pixsize = 23.4;
 
-    fSao->SetPixSize(pixsize/3600);
+    fSao->SetPixSize(pixsize);
 
     TString txt;
@@ -586,5 +586,5 @@
             const Float_t pixsize = atof(fPixSize->GetText());
             cout << "Pixel Size changed to " << pixsize << "\"/pix" << endl;
-            fSao->SetPixSize(pixsize/3600);
+            fSao->SetPixSize(pixsize);
         }
         return kTRUE;
Index: trunk/MagicSoft/Cosy/gui/MGSkyPosition.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGSkyPosition.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGSkyPosition.h	(revision 4076)
@@ -9,5 +9,5 @@
 
 
-#ifndef MGEMBEDDEDCANVAS_H
+#ifndef COSY_MGEmbeddedCanvas
 #include "MGEmbeddedCanvas.h"
 #endif
Index: trunk/MagicSoft/Cosy/gui/MGTPoint.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGTPoint.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGTPoint.cc	(revision 4076)
@@ -151,5 +151,5 @@
     const Double_t pixsize = 23.4;
 
-    fSao->SetPixSize(pixsize/3600);
+    fSao->SetPixSize(pixsize);
 
     TString txt;
@@ -225,5 +225,5 @@
             const Float_t pixsize = atof(fPixSize->GetText());
             cout << "Pixel Size changed to " << pixsize << "\"/pix" << endl;
-            fSao->SetPixSize(pixsize/3600);
+            fSao->SetPixSize(pixsize);
         }
         return kTRUE;
Index: trunk/MagicSoft/Cosy/gui/MGVelocity.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGVelocity.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGVelocity.cc	(revision 4076)
@@ -181,6 +181,6 @@
     // calculate actual time for planet positions
     //
-    float vx = zdaz.Az()*3600.; // ["/min]
-    float vy = zdaz.Zd()*3600.; // ["/min]
+    float vx = zdaz.Az(); // [U_mot/min]
+    float vy = zdaz.Zd(); // [U_mot/min]
 
     int pixx = (int)(vx*fScale/fPix);
Index: trunk/MagicSoft/Cosy/gui/MGVelocity.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGVelocity.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/gui/MGVelocity.h	(revision 4076)
@@ -8,5 +8,5 @@
 //   Version: V1.0 (1-8-2000)
 
-#ifndef MGEMBEDDEDCANVAS_H
+#ifndef COSY_MGEmbeddedCanvas
 #include "MGEmbeddedCanvas.h"
 #endif
Index: trunk/MagicSoft/Cosy/leds.txt
===================================================================
--- trunk/MagicSoft/Cosy/leds.txt	(revision 4075)
+++ trunk/MagicSoft/Cosy/leds.txt	(revision 4076)
@@ -1,6 +1,6 @@
-321 535  -1.2 -1.0
-573 460  -2.0  0.9
-633 204   0.0 -1.6
-446  25   0.0  0.0
-193  95   2.0  1.0
-118 347   0.0  9.1
+260 83  0 0
+147 321 0 0
+296 540 0 0
+525 61  0 0
+676 280 0 0
+561 519 0 0
Index: trunk/MagicSoft/Cosy/main/MCaos.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MCaos.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/main/MCaos.cc	(revision 4076)
@@ -307,5 +307,5 @@
 }
 
-void MCaos::Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t)
+Ring MCaos::Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t)
 {
     Leds &leds = *fLeds;
@@ -344,13 +344,7 @@
 
     Rings rings;
-    rings.CalcRings(leds, 266, 272);
+    rings.CalcRings(leds, 266, 268);
 
     const Ring &center = rings.GetCenter();
-
-    f.DrawCircle(center, 0x80);
-    f.DrawCircle(center,   5.0, 0x80);
-    f.DrawCircle(center, 115.0, 0x80);
-    f.DrawCircle(center, 190.0, 0x80);
-    // f.MarkPoint(center.GetX(), center.GetY(), 0xa0);
 
     // FIXME!
@@ -380,4 +374,5 @@
     }
 
+    return center;
     /*
         if (fCaosAnalyse->IsEntryEnabled(IDM_kStopAnalyse))
Index: trunk/MagicSoft/Cosy/main/MCaos.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MCaos.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/main/MCaos.h	(revision 4076)
@@ -4,4 +4,7 @@
 #ifndef CAOS_Leds
 #include "Leds.h"
+#endif
+#ifndef CAOS_Ring
+#include "Ring.h"
 #endif
 
@@ -68,5 +71,5 @@
     void ResetHistograms();
 
-    void Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t);
+    Ring Run(byte *img, bool printl, bool printr, const ZdAz &pos, const MTime &t);
 };
 
Index: trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 4076)
@@ -1,3 +1,2 @@
-#include "MCosy.h"
 #include "MCosy.h"
 
@@ -22,4 +21,6 @@
 #include "MStarguider.h"
 #include "SlaStars.h"
+#include "MPointing.h"
+#include "MTracking.h"
 
 #include "slalib/slalib.h"  // FIXME: REMOVE
@@ -31,19 +32,4 @@
 
 typedef struct tm tm_t;
-
-/*
-#define GEAR_RATIO_ALT  2475.6 // [U_mot/U_tel(360deg)]
-#define GEAR_RATIO_AZ   5891.7 // [U_mot/U_tel(360deg)]
-
-#define RES_RE           500   // [re/U_mot]
-#define RES_SE         16384   // [se/U_tel(360deg)]
-*/
-/*
- #define GEAR_RATIO_ALT (75.55*16384/1500) // 75.25 VERY IMPORTANT! unit=U_mot/U_tel
- #define GEAR_RATIO_AZ  (179.8*16384/1500)  // VERY IMPORTANT! unit=U_mot/U_tel
-*/
-
-//const XY kGearRatio (GEAR_RATIO_ALT*RES_RE/RES_SE, GEAR_RATIO_AZ*RES_RE/RES_SE);   //[re/se]
-//const XY kGearRatio2(GEAR_RATIO_ALT*RES_RE/360.0,  GEAR_RATIO_AZ*RES_RE/360.0);    //[re/deg]
 
 /* +===================================+
@@ -54,29 +40,4 @@
 //#define EXPERT
 #undef EXPERT
-
-double MCosy::Rad2SE(double rad) const
-{
-    return 16384.0/k2Pi*rad;
-}
-
-double MCosy::Rad2ZdRE(double rad) const
-{
-    return 16384.0/k2Pi*rad*kGearRatio.X();
-}
-
-double MCosy::Rad2AzRE(double rad) const
-{
-    return 16384.0/k2Pi*rad*kGearRatio.Y();
-}
-
-double MCosy::Deg2ZdRE(double rad) const
-{
-    return rad*kGearRatio2.X();
-}
-
-double MCosy::Deg2AzRE(double rad) const
-{
-    return rad*kGearRatio2.Y();
-}
 
 /*
@@ -191,40 +152,4 @@
 // --------------------------------------------------------------------------
 //
-// request the current positions from the rotary encoders.
-// use GetRePos to get the psotions. If the request fails the function
-// returns kFALSE, otherwise kTRUE
-//
-Bool_t MCosy::RequestRePos()
-{
-    //
-    // Send request
-    //
-    fMac2->RequestSDO(0x6004);
-    fMac1->RequestSDO(0x6004);
-
-    //
-    // Wait until the objects are received.
-    //
-    fMac2->WaitForSdo(0x6004);
-    fMac1->WaitForSdo(0x6004);
-
-    //
-    // If waiting was not interrupted everything is ok. return.
-    //
-    if (!(Break() || HasError() || HasZombie()))
-        return kTRUE;
-
-    //
-    // If the waiting was interrupted due to a network error,
-    // print some logging message.
-    //
-    if (HasError())
-        lout << "Error while requesting re pos from Macs (SDO #6004)" << endl;
-
-    return kFALSE;
-}
-
-// --------------------------------------------------------------------------
-//
 //  reads the Rotary encoder positions from the last request of the Macs.
 //
@@ -253,65 +178,4 @@
 // --------------------------------------------------------------------------
 //
-//  set the velocity and accelerations for position maneuvers.
-//
-//  The acceleratin is set as given (in percent of maximum).
-//  The velocity is given in percent, depending on the ratio (<1 or >1)
-//  one of the axis becomes a slower velocity. This is used for maneuvers
-//  in which both axis are moved synchromously and should reach their
-//  target position at the same time.
-//
-void MCosy::SetPosVelocity(const Float_t ratio, Float_t vel)
-{
-    //
-    // Set velocities
-    //
-    const int vr = fMac1->GetVelRes();
-
-    vel *= vr;
-
-    if (ratio <1)
-    {
-        fMac1->SetVelocity(vel);
-        fMac2->SetVelocity(vel*ratio);
-    }
-    else
-    {
-        fMac1->SetVelocity(vel/ratio);
-        fMac2->SetVelocity(vel);
-    }
-}
-
-// --------------------------------------------------------------------------
-//
-// Does a relative positioning.
-//
-// The steps to move are given in a ZdAz object relative to the current
-// position. The coordinates are given in Roteryencoder steps.
-// Axis 1 is moved only if axe1==kTRUE, Axis 2 is moved only
-// if Axis 2==kTRUE. The function waits for the movement to be finished.
-//
-void MCosy::DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2)
-{
-    if (HasZombie())
-        return;
-
-    SetStatus(MDriveCom::kMoving);
-
-    if (axe1) fMac2->StartRelPos(rd.Zd());
-    if (axe2) fMac1->StartRelPos(rd.Az());
-#ifdef EXPERT
-    cout << "Waiting for positioning..." << flush;
-#endif
-    if (axe1) fMac2->WaitForSdo(0x6004, 1);
-    if (axe2) fMac1->WaitForSdo(0x6004, 1);
-
-    WaitForEndMovement();
-#ifdef EXPERT
-    cout << "done." << endl;
-#endif
-}
-
-// --------------------------------------------------------------------------
-//
 // check for a break-signal (from the msgqueue) and errors.
 //
@@ -341,6 +205,5 @@
         return;
 
-    MTime t;
-    t.Now();
+    MTime t(-1);
     lout << t << " - MCosy::WaitForEndMovement aborted...";
     if (Break())
@@ -434,393 +297,4 @@
 }
 
-// --------------------------------------------------------------------------
-//
-// Move the telescope to the given position. The position must be given in
-// a ZdAz object in rad.
-//
-// The first positioning is done absolutely. If we didn't reach the
-// correct psotion we try to correct for this by 10 relative position
-// maneuvers. If this doesn't help positioning failed.
-//
-// As a reference the shaftencoder values are used.
-//
-int MCosy::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
-{
-    const ZdAz d = dst*kRad2Deg;
-
-    MTime t;
-    t.Now();
-    lout << t << " - Target Position: " << d.Zd() << "deg, " << d.Az() << "deg (Zd/Az)" << endl;
-
-    //
-    // Calculate new target position (shortest distance to go)
-    //
-    const ZdAz src = GetSePos(); // [se]
-
-    //
-    // Make sure that the motors are in sync mode (necessary if the
-    // MACS has been rebooted from a Zombie state.
-    //
-    //InitSync();
-    //if (fMac3->IsZombieNode())
-    //    return false;
-
-    //
-    // Because we agreed on I don't search for the shortest move
-    // anymore
-    //
-    // const ZdAz dest = CorrectTarget(src, dst);
-    //
-    ZdAz bend = fBending(dst); // [rad]
-
-    const ZdAz dest = bend*16384/2/TMath::Pi(); // [se]
-
-    if (!CheckRange(bend))
-        return kFALSE;
-
-    bend *= kRad2Deg;
-    fZdAzSoll = dst;
-
-    cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
-    cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
-    cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
-    cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
-
-    //
-    // Set velocities
-    //
-    const int vr = fMac1->GetVelRes();
-
-    int i;
-    for (i=0; i<(track?1:10) && !(Break() || HasError() || HasZombie()); i++)
-    {
-
-        lout << "- Step #" << i << endl;
-        //
-        // Get Shaft Encoder Positions
-        //
-        const ZdAz p=GetSePos();
-
-        //
-        // calculate control deviation and rounded cd
-        //
-        ZdAz rd = dest-p; // [se]
-
-        // ===========================================
-        const ZdAz ist = dst-rd*TMath::Pi()/8192;
-
-        const double p1 = ist.Zd()-19.0605/kRad2Deg;
-        const double p2 = dst.Zd()-19.0605/kRad2Deg;
-
-        const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*8192/TMath::Pi();
-        const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*8192/TMath::Pi();
-        // ===========================================
-
-        ZdAz cd = rd;     // [se]
-        cd.Round();
-
-        //
-        // Check if there is a control deviation on the axis
-        //
-        const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
-        const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
-
-        //
-        // check if we reached the correct position already
-        //
-        if (!cdzd && !cdaz)
-        {
-            t.Now();
-            lout << t << " - Positioning done in " << i << (i==1?" step.":" steps.") << endl;
-            SetStatus(MDriveCom::kStopped);
-            return TRUE;
-        }
-
-        //
-        // change units from se to re
-        //
-        rd *= kGearRatio; // [re]
-        rd.Zd(f2-f1);
-
-        //
-        // Initialize Velocities so that we reach both positions
-        // at the same time
-        //
-        if (i)
-        {
-            fMac1->SetAcceleration(0.1*vr);
-            fMac2->SetAcceleration(0.1*vr);
-
-            fMac1->SetDeceleration(0.1*vr);
-            fMac2->SetDeceleration(0.1*vr);
-
-            SetPosVelocity(1.0, 0.05);
-        }
-        else
-        {
-            if (rd.Az()>-15*kGearRatio.Y() && rd.Az()<15*kGearRatio.Y())
-            {
-#ifdef EXPERT
-                cout << " -------------- LO ---------------- " << endl;
-#endif
-                fMac1->SetAcceleration(0.05*vr);
-                fMac1->SetDeceleration(0.05*vr);
-            }
-            else
-            {
-#ifdef EXPERT
-                cout << " -------------- HI ---------------- " << endl;
-                fMac1->SetAcceleration(0.4*vr);// 0.4
-                fMac1->SetDeceleration(0.4*vr);// 0.4
-#else
-                fMac1->SetAcceleration(0.2*vr);
-                fMac1->SetDeceleration(0.1*vr);
-#endif
-            }
-
-#ifdef EXPERT
-            fMac2->SetAcceleration(0.4*vr);// 0.4
-            fMac2->SetDeceleration(0.4*vr);// 0.4
-            SetPosVelocity(fabs(rd.Ratio()), 0.2); // fast: 0.6, slow: 0.2
-#else
-            fMac2->SetAcceleration(0.2*vr);
-            fMac2->SetDeceleration(0.1*vr);
-            SetPosVelocity(fabs(rd.Ratio()), 0.1);
-#endif
-        }
-
-        rd.Round();
-
-        // FIXME? Check for Error or Zombie?
-
-        /*
-         cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
-         cout << " + APOS:  Zd=" << setw(6) << p.Zd()  << "se   Az=" << setw(6) << p.Az()  << "se" << endl;
-         cout << " +       dZd=" << setw(6) << cd.Zd() << "se  dAz=" << setw(6) << cd.Az() << "se" << endl;
-         cout << " +       dZd=" << setw(6) << rd.Zd() << "re  dAz=" << setw(6) << rd.Az() << "re" << endl;
-         cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X()  << "se   Az=" << setw(6) << kGearRatio.Y()  << "se" << endl;
-        */
-
-        //
-        // repositioning (relative)
-        //
-
-        lout << "- Do Relative Positioning..." << endl;
-        DoRelPos(rd, cdzd, cdaz);
-        lout << "- Relative Positioning Done" << endl;
-    }
-    if (i==1 && track && !(Break() || HasError() || HasZombie()))
-    {
-        t.Now();
-        lout << t << " - Positioning done." << endl;
-        SetStatus(MDriveCom::kStopped);
-        return TRUE;
-    }
-
-    if (i<10)
-        StopMovement();
-    else
-        SetStatus(MDriveCom::kStopped);
-
-    t.Now();
-    lout << t << " - Warning: Requested position not reached (i=" << dec << i << ")" << endl;
-    return FALSE;
-}
-
-// --------------------------------------------------------------------------
-//
-// Sets the tracking velocity
-//
-// The velocities are given in a ZdAz object in re/min. Return kTRUE
-// in case of success, kFALSE in case of failure.
-//
-Bool_t MCosy::SetVelocity(const ZdAz &v)
-{
-    //
-    // Send the new velocities for both axes.
-    //
-    fMac2->SendSDO(0x3006, 1, (LWORD_t)v.Zd());  // SetRpmVelocity [re/min]
-    fMac1->SendSDO(0x3006, 1, (LWORD_t)v.Az());  // SetRpmVelocity [re/min]
-
-    //
-    // Wait for the objects to be acknoledged.
-    //
-    fMac2->WaitForSdo(0x3006, 1);
-    fMac1->WaitForSdo(0x3006, 1);
-
-    //
-    // If the waiting for the objects wasn't interrupted return kTRUE
-    //
-    if (!(Break() || HasError() || HasZombie()))
-        return kTRUE;
-
-    //
-    // print a message if the interruption was due to a Can-node Error
-    //
-    if (HasError())
-        lout << "Error while setting velocity (SDO #3006)" << endl;
-
-    return kFALSE;
-}
-
-// --------------------------------------------------------------------------
-//
-// Initializes Tracking mode
-//
-// Initializes the accelerations of both axes with 90% of the maximum
-// acceleration. Set the status for moving and tracking and starts thr
-// revolution mode.
-//
-bool MCosy::InitTracking()
-{
-    // FIXME? Handling of Zombie OK?
-    if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
-        return false;
-
-    //
-    // Start revolution mode
-    //
-    fMac2->SetAcceleration(0.1*fMac2->GetVelRes());
-    fMac2->SetDeceleration(0.1*fMac2->GetVelRes());
-    if (fMac2->IsZombieNode())
-        return false;
-
-    fMac1->SetAcceleration(0.1*fMac1->GetVelRes());
-    fMac1->SetDeceleration(0.1*fMac1->GetVelRes());
-    if (fMac1->IsZombieNode())
-        return false;
-
-    SetStatus(MDriveCom::kMoving | MDriveCom::kTracking);
-
-    fMac2->SetRpmMode(TRUE);
-    if (fMac2->IsZombieNode())
-        return false;
-
-    fMac1->SetRpmMode(TRUE);
-    if (fMac1->IsZombieNode())
-        return false;
-
-    return true;
-}
-
-// --------------------------------------------------------------------------
-//
-// Limits the speed. 
-//
-// This function should work as a limiter. If a tracking error is too large
-// to be corrected fast enough we would get enormous velocities. These
-// velocities are limited to the maximum velocity.
-//
-Bool_t MCosy::LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const
-{
-    Bool_t rc = kFALSE;
-
-    //
-    // How to limit the speed. If the wind comes and blowes
-    // we cannot forbid changing of the sign. But on the other hand
-    // we don't want fast changes!
-    //
-    ULong_t vrzd = fMac1->GetVelRes();
-    ULong_t vraz = fMac2->GetVelRes();
-
-#define sgn(x) (x<0?-1:1)
-
-    //
-    // When speed changes sign, the maximum allowed speed
-    // is 25% of the |v|
-    //
-    //const Float_t limit    = 0.25;
-
-    //
-    // The maximum allowed speed while tracking is 10%
-    //
-    const Float_t maxtrack = 0.1;
-/*
-    if (sgn(vt->Az()) != sgn(vcalc.Az()))
-        vt->Az(0);
-//    else
-    {
-        if (fabs(vt->Az()) < fabs(vcalc.Az()) *0.5)
-            vt->Az(0.5*vcalc.Az());
-
-        if (fabs(vt->Az()) > fabs(vcalc.Az()) *1.5)
-            vt->Az(1.5*vcalc.Az());
-    }
-
-    if (sgn(vt->Zd()) != sgn(vcalc.Zd()))
-        vt->Zd(0);
-//    else
-    {
-        if (fabs(vt->Zd()) > fabs(vcalc.Az()) *1.5)
-            vt->Zd(1.5*vcalc.Zd());
-
-        if (fabs(vt->Zd()) < fabs(vcalc.Az()) *0.5)
-            vt->Zd(0.5*vcalc.Zd());
-    }
-    */
-   /*
-    if (sgn(vt->Az()) != sgn(vcalc.Az())
-        && fabs(vt->Az()) < limit*fabs(vcalc.Az())
-       )
-        {
-            lout << "Warning: Negative Azimuth speed limit (" << limit*100 << "%) exceeded... set to 0." << endl;
-            vt->Az(0);
-        }
-    else*/
-        if (fabs(vt->Az()) > maxtrack*vraz)
-        {
-            lout << "Warning: Azimuth speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Az()) << " > " << maxtrack*vraz << ")... limited." << endl;
-            vt->Az(maxtrack*vraz*sgn(vcalc.Az()));
-            rc=kTRUE;
-        }
-/*
-    if (sgn(vt->Zd()) != sgn(vcalc.Zd())
-        && fabs(vt->Zd()) < limit*fabs(vcalc.Zd())
-       )
-        {
-            lout << "Warning: Negative Altitude speed limit (" << limit*100 << "%) exceeded... set to 0." << endl;
-            vt->Zd(0);
-        }
-    else
- */       if (fabs(vt->Zd()) > maxtrack*vrzd)
-        {
-            lout << "Warning: Altitude speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Zd()) <<" > " << maxtrack*vrzd << ")... limited." << endl;
-            vt->Zd(maxtrack*vrzd*sgn(vcalc.Zd()));
-            rc=kTRUE;
-        }
-    return rc;
-}
-/*
-Bool_t MCosy::AlignTrackingPos(ZdAz pointing, ZdAz &za) const
-{
-    // pointing [deg]
-    if (pointing.Zd()<0)
-    {
-        pointing.Zd(-pointing.Zd());
-        pointing.Az(pointing.Az()+180);
-    }
-
-    const ZdAz se = GetSePos()*2*TMath::Pi()/16384;   // [rad]
-    const ZdAz unbendedse = fBending.CorrectBack(se)*kRad2Deg; // ist pointing
-
-    do
-    {
-        const Double_t d = unbendedse.Az() - pointing.Az();
-        if (d>-180 && d<=180)
-            break;
-
-        pointing.Az(pointing.Az()+TMath::Sign(360., d));
-    } while (1);
-
-    const Bool_t rc = CheckRange(pointing);
-    za = pointing/kRad2Deg; // [rad]
-
-    if (!rc)
-        lout << "Error: Aligned position out of Range." << endl;
-
-    return rc;
-}
-*/
-
 ZdAz MCosy::AlignTrackingPos(ZdAz pointing) const
 {
@@ -837,5 +311,5 @@
     }
 
-    const ZdAz se = GetSePos()*2*TMath::Pi()/16384;   // [rad]
+    const ZdAz se = GetSePos()*TMath::TwoPi()/kResSE;   // [rad]
     const ZdAz unbendedse = fBending.CorrectBack(se)*kRad2Deg; // ist pointing
 
@@ -897,6 +371,5 @@
 
     dest -= point;
-    dest *= 16384/TMath::Pi()/2; // [se]
-    dest *= -kGearRatio;         // [re]
+    dest *= -kGearTot/TMath::TwoPi(); // [re]
 
     cout << "Using Starguider... dZd=" << dest.Zd() << " dAz=" << dest.Az() << endl;
@@ -905,238 +378,44 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Move the telescope to the given position. The position must be given in
+// a ZdAz object in rad.
+//
+// The first positioning is done absolutely. If we didn't reach the
+// correct psotion we try to correct for this by 10 relative position
+// maneuvers. If this doesn't help positioning failed.
+//
+// As a reference the shaftencoder values are used.
+//
+int MCosy::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
+{
+    MPointing point(this, lout);
+
+//#ifdef EXPERT
+//    point.SetAccDec(0.4, 0.4);
+//    point.SetVelocity(0.2); // fast: 0.6, slow: 0.2
+//#else
+    point.SetPointAccDec(0.2, 0.1);
+    point.SetPointVelocity(0.1);
+//#endif
+
+    return point.SetPosition(dst, track);
+}
+
 void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
 {
-    SlaStars sla(fObservatory);
-
-    //
-    // Position to actual position
-    //
-    sla.Now();
-    ZdAz dest = sla.CalcZdAz(dst);
-
-    lout << sla.GetTime() << ": Track Position " << dst.Ra()*kRad2Deg/15 << "h, " << dst.Dec()*kRad2Deg <<"deg" << endl;
-
-    // FIXME: Determin tracking start point by star culmination
-    if (dest.Az()<-TMath::Pi()/2)
-    {
-        lout << "Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
-        dest.Az(dest.Az() + TMath::Pi()*2);
-    }
-
-    if (dest.Az()>3*TMath::Pi()/2)
-    {
-        lout << "Substracting 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
-        dest.Az(dest.Az() -TMath::Pi()*2);
-    }
-
-    if (!SetPosition(dest, kTRUE))
-    //if (!SetPosition(dest, kFALSE))
-    {
-        lout << "Error: Cannot start tracking, positioning failed." << endl;
-        return;
-    }
-
-    //
-    // calculate offset from present se position
-    //
-    const ZdAz sepos = GetSePos()*kGearRatio;
-
-    if (!RequestRePos())
-        return;
-
-    //
-    // Estimate Offset before starting to track
-    //
-    fOffset = sepos-GetRePos();
-
-    /*
-     cout << "Sepos:  " << sepos.Zd() << "re, " << sepos.Az() << "re" << endl;
-     cout << "Repos:  " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
-     cout << "Offset: " << fOffset.Zd() << "re, " << fOffset.Az() << "re" << endl;
-     */
-
-    //
-    // Init accelerations and Rpm Mode
-    //
-    if (!InitTracking())
-    {
-        StopMovement();
-        return;
-    }
-
-    XY xy(Rad2Deg(dst.Ra())*24/360, Rad2Deg(dst.Dec()));
-
-    sla.Now();
-//    lout << sla.GetTime() << " - Start tracking:";
-//    lout << " Ra: " << xy.X() << "h  " << "Dec: " << xy.Y() << "\xb0" << endl;
-
-/*#ifdef EXPERT
-    ofstream fout("coordinates.txt");
-    fout << xy;
-    fout.close();
-#endif
-*/    //
-    // Initialize Tracker (slalib or starguider)
-    //
-    fRaDec = dst;
-    fBackground = kBgdTracking;
-
-    ZdAz pos = sla.CalcZdAz(fRaDec);
-
-    lout << sla.GetTime() << " - Start Tracking: Ra=" <<xy.X() << "h Dec=";
-    lout << xy.Y() << "\xb0 @ Zd=" << pos.Zd()*kRad2Deg <<"deg Az=" << pos.Az()*kRad2Deg <<"deg" << endl;
-
-//---    ofstream fout("log/cosy.pos");
-//---    fout << "Tracking:";
-//---    fout << " Ra: " << Rad2Deg(dst.Ra())  << "\x9c  ";
-//---    fout << "Dec: " << Rad2Deg(dst.Dec()) << "\x9c" << endl << endl;
-//---    fout << "     Mjd/10ms    V/re/min/4" << endl;
-
-    //
-    // We want to reach the theoretical position exactly in about 0.5s
-    //
-    // *OLD*const float dt = 1;  // 1 second
-    const float dt = 5;//3;  // 2 second
-    while (!(Break() || HasError() || HasZombie()))
-    {
-        //
-        // Request Target position for this moment
-        //
-        sla.Now(dt);
-
-        //
-        // Request theoretical Position for a time in the future (To+dt) from CPU
-        //
-         const ZdAz pointing = sla.CalcZdAz(fRaDec); // soll pointing [rad]
-
-        //lout << sla.GetTime() << pointing.Zd()*kRad2Deg << " " << pointing.Az()*kRad2Deg << endl;
-        /*
-        ZdAz dest;
-        if (!AlignTrackingPos(pointing, dest))
-            break;
-            */
-        ZdAz dest = AlignTrackingPos(pointing);
-
-        // lout << "DEST: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
-
-        ZdAz vcalc = sla.GetApproxVel(fRaDec) * kGearRatio2*4./60.; 
-        //lout << "Vcalc: " << dest.Zd() << " " << dest.Az() << endl;
-        vcalc *= kGearRatio2*4./60.; // [re/min]
-
-        float dtime = -1;
-        if (kFALSE /*fUseStarguider*/)
-            dtime = Starguider(sla.GetMjd(), dest);
-
-        if (dtime<0)
-        {
-            dest = fBending(dest);       // [rad]
-
-            //lout << "DEST-BEND: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
-              
-            if (!CheckRange(dest))
-                break;
-
-            dest *= 16384/TMath::Pi()/2; // [se]
-            dest *= kGearRatio;          // [re]
-
-            //
-            // Request absolute position of rotary encoder from Macs
-            //
-            if (!RequestRePos())
-                break;
-
-            //
-            // distance between (To+dt) and To [re]
-            // position time difference < 5usec
-            // fOffset does the synchronization between the
-            // Shaft- and the rotary encoders
-            dest -= GetRePos() + fOffset;
-
-            dtime = dt;
-
-            ZdAz repos = GetRePos();
-    //        lout << "Repos: " << repos.Zd()/kGearRatio.X() << " " << repos.Az()*kGearRatio.Y() << endl;
-   //         repos /= kGearRatio;
-            repos /= 16384/TMath::Pi()/2;
-            repos *= kRad2Deg;
-        }
-
-        //
-        // Velocity to go [re/min] to reach the right position at time t+dt
-        // correct for the duration of RaDec2AltAz
-        //
-        const ZdAz v = dest*60.0/(dtime/*-(fMac2->GetTime()-sla)*/);
-
-        //
-        // calculate real velocity of future [re/min]
-        // believing the Macs manual '/4' shouldn't be necessary, but it is.
-        //
-        ZdAz vt = v/4;
-        if (LimitSpeed(&vt, vcalc))
-        {
-            lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
-            lout << "vt: " << vt.Zd() << " " << vt.Az() << "re/min" << endl;
-            lout << "Dest: " << dest.Zd() << " " << dest.Az() << endl;
-        }              
-        vt.Round();
-
-        //
-        // check if the drive is fast enough to follow the star
-        //
-        if (vt.Zd()>.9*fMac1->GetVelRes() || vt.Az()>.9*fMac2->GetVelRes())
-        {
-            lout << "Error: Tracking speed faster than 90% of possible maximum velocity." << endl;
-            break;
-        }
-
-        //
-        // Set theoretical velocity (as early after calculation as possible)
-        // Maybe we should attenuate the changes
-        //
-        if (!SetVelocity(vt))
-            break;
-
-        //
-        // Now do 'unnecessary' things
-        //
-        fVelocity = vt/kGearRatio2*4;
-
-//---        const double mjd = fMac2->GetMjd();
-//---        fout << setprecision(15) << setw(17) << mjd*60.*60.*24. << " ";
-//---        fout << setw(4) << vt.Zd() << " ";
-//---        fout << setw(4) << vt.Az() << endl;
-        //
-        // FIXME? Calculate an accuracy for the tracking system?
-        // How good do we reach the calculated position in 'real'
-        // re valus?
-        //
-
-
-        //
-        // Update speed as often as possible.
-        // make sure, that dt is around 10 times larger than the
-        // update time
-        //
-        //
-        // The loop should not be executed faster than the ramp of
-        // a change in the velocity can be followed.
-        // (This is important on fast machines >500MHz)
-        //
-        /*
-        MTimeout t(1000);
-        while (!t.HasTimedOut())
-            usleep(1);
-         */
-        usleep(1000000); // 1s
-        cout << "." << flush;
-        //usleep(50000); // 0.05s
-    }
-
-    sla.Now();
-
-    fBackground = kBgdNone;
-    StopMovement();
-
-    lout << sla.GetTime() << " - Tracking stopped." << endl;
+    MTracking track(this, lout);
+    track.SetOut(fOutRep);
+//#ifdef EXPERT
+//    track.SetPointAccDec(0.4, 0.4);
+//    track.SetPointVelocity(0.2); // fast: 0.6, slow: 0.2
+//#else
+    track.SetPointAccDec(0.2, 0.1);
+    track.SetPointVelocity(0.1);
+//#endif
+    track.SetTrackAccDec(0.1, 0.1);
+
+    track.TrackPosition(dst);
 }
 
@@ -1201,45 +480,4 @@
 }
 
-void MCosy::StopTracking()
-{
-    //
-    // Set status to Stopping
-    //
-    SetStatus(MDriveCom::kStopping);
-
-    //
-    // set deceleration to 50%
-    //
-    cout << "Stopping tracking (dec=20%)..." << endl;
-    fMac1->SetDeceleration(0.2*fMac1->GetVelRes());
-    fMac2->SetDeceleration(0.2*fMac2->GetVelRes());
-
-    fMac2->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
-    fMac1->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
-    fMac2->WaitForSdo(0x3006, 1);
-    fMac1->WaitForSdo(0x3006, 1);
-
-    cout << "Waiting for end of movement..." << endl;
-    WaitForEndMovement();
-
-    //
-    // Wait for the objects to be OKed.
-    //
-    fMac1->SetRpmMode(FALSE);
-    fMac2->SetRpmMode(FALSE);
-
-    //
-    // Wait for the movement to really be finished.
-    //
-    //cout << "Waiting for end of movement..." << endl;
-    //WaitForEndMovement();
-
-    //
-    // Check whether everything works fine.
-    //
-    CheckForError();
-    cout << "Movement stopped." << endl;
-}
-
 bool MCosy::CheckNetwork()
 {
@@ -1281,5 +519,5 @@
 
     case WM_STOP:
-        cout << "MCosy::Proc: Stop." << endl;
+        //cout << "MCosy::Proc: Stop." << endl;
         if (!CheckNetwork())
             return (void*)0xebb0;
@@ -1331,5 +569,5 @@
     case WM_TPOINT:
         {
-            cout << "WM_TPoint: start." << endl;
+            //cout << "WM_TPoint: start." << endl;
             SlaStars sla(fObservatory);
             sla.Now();
@@ -1340,28 +578,45 @@
             AltAz za=sla.CalcAltAz(rd*kDeg2Rad)*kRad2Deg;
 
+            if (!fOutTp)
+            {
+                //
+                // open tpoint file
+                //
+                const TString name = GetFileName("tpoint/tpoint_%s.txt");
+                cout << "TPoint-Cosy File ********* " << name << " ********** " << endl;
+
+                fOutTp = new ofstream(name);
+                *fOutTp << "Magic Model  TPOINT data file" << endl;
+                *fOutTp << ": ALTAZ" << endl;
+                *fOutTp << "49 48 0 ";
+                *fOutTp << sla.GetTime().Year() << " " << sla.GetTime().Month() << " " << sla.GetTime().Day() << " ";
+                *fOutTp << /*"20 1013.25 300 0.5 0.55 0.0065" <<*/ endl;
+                // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
+            }
+
             cout << "     Alt/Az: " << za.Alt() << "° " << za.Az() << "°" << endl;
-            *tpout << setprecision(7) << za.Az() << " " << za.Alt() << " ";
-
-            ZdAz sepos = GetSePos()*TMath::Pi()*2/16384;;
+            *fOutTp << setprecision(7) << za.Az() << " " << za.Alt() << " ";
+
+            ZdAz sepos = GetSePos()*TMath::TwoPi()/kResSE;
             za.Set(TMath::Pi()/2-sepos.Zd(), sepos.Az());
             za *= kRad2Deg;
 
             cout << "     SE-Pos: " << za.Alt() << "° " << za.Az() << "°" << endl;
-            *tpout << fmod(za.Az()+360, 360) << " " << za.Alt() << " ";
+            *fOutTp << fmod(za.Az()+360, 360) << " " << za.Alt() << " ";
 
             if (fStarguider)
             {
                 XY tp = fStarguider->GetCoordinates();
-                *tpout << 90-tp.X() << " " << tp.Y() << " ";
+                *fOutTp << 90-tp.X() << " " << tp.Y() << " ";
             }
 
-            *tpout << rd.Ra()/15 << " " << rd.Dec() << " " << setprecision(11) << sla.GetMjd() << endl;
-
-            cout << "WM_TPoint: done. (return 0xaffe)" << endl;
+            *fOutTp << rd.Ra()/15 << " " << rd.Dec() << " " << setprecision(11) << sla.GetMjd() << endl;
+
+            //cout << "WM_TPoint: done. (return 0xaffe)" << endl;
         }
         return (void*)0xca1b;
 
     case WM_TRACKPOS:
-        cout << "WM_TrackPosition: start." << endl;
+        //cout << "WM_TrackPosition: start." << endl;
         {
             if (!CheckNetwork())
@@ -1376,13 +631,11 @@
 
             RaDec rd = sla.CalcRaDec(dest);
-            cout << dest.Zd()*180/3.1415 << " " << dest.Az()*180/3.1415 << endl;
-            cout << rd.Ra()*12/3.1415 << " " << rd.Dec()*180/3.1415 << endl;
             TrackPosition(rd);
         }
-        cout << "WM_TrackPosition: done. (return 0xabcd)" << endl;
+        //cout << "WM_TrackPosition: done. (return 0xabcd)" << endl;
         return (void*)0xabcd;
 
     case WM_POSITION:
-        cout << "WM_Position: start." << endl;
+        //cout << "WM_Position: start." << endl;
         {
             if (!CheckNetwork())
@@ -1392,9 +645,9 @@
             SetPosition(dest*kDeg2Rad);
         }
-        cout << "WM_Position: done. (return 0x7777)" << endl;
+        //cout << "WM_Position: done. (return 0x7777)" << endl;
         return (void*)0x7777;
 
     case WM_POSITION1:
-        cout << "WM_Position1: start." << endl;
+        //cout << "WM_Position1: start." << endl;
         {
             if (!CheckNetwork())
@@ -1404,27 +657,27 @@
             SetPosition(dest*kDeg2Rad, kTRUE);
         }
-        cout << "WM_Position: done. (return 0x7777)" << endl;
+        //cout << "WM_Position: done. (return 0x7777)" << endl;
         return (void*)0x7777;
 
     case WM_TESTSE:
-        cout << "WM_TestSe: start." << endl;
+        //cout << "WM_TestSe: start." << endl;
         fBackground = mp ? kBgdSeTest : kBgdNone;
-        cout << "WM_TestSe: done. (return 0x1e51)" << endl;
+        //cout << "WM_TestSe: done. (return 0x1e51)" << endl;
         return (void*)0x1e51;
 
     case WM_GEAR:
-        cout << "WM_Gear: start." << endl;
+        //cout << "WM_Gear: start." << endl;
         fBackground = mp ? kBgdGear : kBgdNone;
-        cout << "WM_Gear: done. (return 0xfeaf)" << endl;
+        //cout << "WM_Gear: done. (return 0xfeaf)" << endl;
         return (void*)0xfeaf;
 
     case WM_DISPLAY:
-        cout << "WM_Display: start." << endl;
+        //cout << "WM_Display: start." << endl;
         fTriggerDisplay = kTRUE;
-        cout << "WM_Disply: done. (return 0xd1e1)" << endl;
+        //cout << "WM_Disply: done. (return 0xd1e1)" << endl;
         return (void*)0xd1e1;
 
     case WM_TRACK:
-        cout << "WM_Track: START" << endl;
+        //cout << "WM_Track: START" << endl;
         {
             RaDec dest = ((RaDec*)mp)[0];
@@ -1435,27 +688,27 @@
             TrackPosition(dest*kDeg2Rad);
         }
-        cout << "WM_Track: done. (return 0x8888)" << endl;
+        //cout << "WM_Track: done. (return 0x8888)" << endl;
         return (void*)0x8888;
 
     case WM_NEWTRACK:
-        cout << "WM_NewTrack: START" << endl;
+        //cout << "WM_NewTrack: START" << endl;
         fRaDec = *((RaDec*)mp);
-        cout << "WM_NewTrack: done. (return 0x9999)" << endl;
+        //cout << "WM_NewTrack: done. (return 0x9999)" << endl;
         return (void*)0x9999;
 
     case WM_LOADBENDING:
-        cout << "WM_LoadBending: START" << endl;
+        //cout << "WM_LoadBending: START" << endl;
         fBending.Load("bending.txt");
-        cout << "WM_LoadBending: done. (return 0xbe0d)" << endl;
+        //cout << "WM_LoadBending: done. (return 0xbe0d)" << endl;
         return (void*)0xbe0d;
 
     case WM_RESETBENDING:
-        cout << "WM_ResetBending: START" << endl;
+        //cout << "WM_ResetBending: START" << endl;
         fBending.Reset();
-        cout << "WM_ResetBending: done. (return 0xbe0e)" << endl;
+        //cout << "WM_ResetBending: done. (return 0xbe0e)" << endl;
         return (void*)0xbe0e;
 
     case WM_HOME:
-        cout << "WM_Home: START" << endl;
+        //cout << "WM_Home: START" << endl;
         if (!CheckNetwork())
             return (void*)0xebb0;
@@ -1485,5 +738,5 @@
             */
         }
-        cout << "WM_Home: done. (return 0x403e)" << endl;
+        //cout << "WM_Home: done. (return 0x403e)" << endl;
         return (void*)0x403e;
 
@@ -1510,5 +763,5 @@
             a1 *= kRad2Deg;
 
-            const ZdAz a2 = a1*16384/360;
+            const ZdAz a2 = a1*kResSE/360;
 
             cout << "Zd/Az bended:  " << a1.Zd() << "° " << a1.Az() << "°" << endl;
@@ -1519,5 +772,5 @@
     case WM_ENDSWITCH:
         {
-            ZdAz pos = GetSePos()*TMath::Pi()*2/16384;
+            ZdAz pos = GetSePos()*TMath::TwoPi()/kResSE;
             pos = fBending.SubtractOffsets(pos)*kRad2Deg;
 
@@ -1575,45 +828,49 @@
 
     cout << "Reading gear ratios..." << flush;
-    const Double_t gaz = env.GetValue("Az_GearRatio[U_mot/U_tel]", 1000.0);
-    const Double_t gzd = env.GetValue("Zd_GearRatio[U_mot/U_tel]", 1000.0);
-
-    Double_t resreaz = 0;
+    kGear.Y(env.GetValue("Az_GearRatio[U_mot/U_tel]", 1000.0));
+    kGear.X(env.GetValue("Zd_GearRatio[U_mot/U_tel]", 1000.0));
+
+    kResRE.Y(0);
     if (fMac1 && !fMac1->IsZombieNode())
-        resreaz = fMac1->GetRes();
+        kResRE.Y(fMac1->GetRes());
     else
         if (fMac3 && !fMac3->IsZombieNode())
-            resreaz = fMac3->GetRes();
+            kResRE.Y(fMac3->GetRes());
         else
-            resreaz = env.GetValue("Az_ResRE[re/U_mot]", 1500);
-
-    Double_t resrezd = 0;
+            kResRE.Y(env.GetValue("Az_ResRE[re/U_mot]", 1500));
+
+    kResRE.X(0);
     if (fMac2 && !fMac2->IsZombieNode())
-        resrezd = fMac2->GetRes();
+        kResRE.X(fMac2->GetRes());
     else
-        resrezd = env.GetValue("Zd_ResRE[re/U_mot]", 1500);
-
-    Double_t ressezd = 0;
+        kResRE.X(env.GetValue("Zd_ResRE[re/U_mot]", 1500));
+
+    kResSE.X(0);
     if (fZd1 && !fZd1->IsZombieNode())
-        ressezd = fZd1->GetPhysRes();
+        kResSE.X(fZd1->GetPhysRes());
     else
         if (fZd2 && !fZd2->IsZombieNode())
-            ressezd = fZd2->GetPhysRes();
+            kResSE.X(fZd2->GetPhysRes());
         else
-            ressezd = env.GetValue("Zd_ResSE[se/U_mot]", 16384);
-
-    Double_t resseaz = 0;
+            kResSE.X(env.GetValue("Zd_ResSE[se/U_mot]", 16384));
+
+    kResSE.Y(0);
     if (fAz && !fAz->IsZombieNode())
-        resseaz = fAz->GetPhysRes();
+        kResSE.Y(fAz->GetPhysRes());
     else
-        resseaz = env.GetValue("Az_ResSE[se/U_mot]", 16384);
-
-    kGearRatio.Set (gzd*resrezd*4/ressezd, gaz*resreaz*4/resseaz);  //[re/se]
-    kGearRatio2.Set(gzd*resrezd*4/360.0,   gaz*resreaz*4/360.0);    //[re/deg]
+        kResSE.Y(env.GetValue("Az_ResSE[se/U_mot]", 16384));
+
+    // believing the Macs manual '*4' shouldn't be necessary, but it is.
+    // Because the a RE is 4 quad counts.
+    // Calculating speeds we have to convert back to qc
+    kResRE  *= 4;
+    kGearTot = kResRE*kGear;
+
     cout << "done." << endl;
 
     cout << " * Setting Gear Ratios:" << endl;
     cout << "   --------------------" << endl;
-    cout << " *  X: " << gzd << "*" << resrezd << "/" << ressezd << "=4*" << kGearRatio.X() << endl;
-    cout << " *  Y: " << gaz << "*" << resreaz << "/" << resseaz << "=4*" << kGearRatio.Y() << endl;
+    cout << " *  X: " << kGear.X() << "*" << kResRE.X()/4 << "/" << kResSE.X() << "=4*" << kGearTot.X() << "/" << kResSE.X() << endl;
+    cout << " *  Y: " << kGear.Y() << "*" << kResRE.Y()/4 << "/" << kResSE.Y() << "=4*" << kGearTot.Y() << "/" << kResSE.Y() << endl;
 }
 
@@ -1632,133 +889,4 @@
     fMac3->SetDeceleration(0.2*res);
     fMac3->StartPosSync();
-}
-
-void MCosy::TalkThreadTracking()
-{
-    if (fZd1->IsZombieNode() && fZd2->IsZombieNode())
-        return;
-
-    if (fAz->IsZombieNode())
-        return;
-
-    if (!fMac1 || !fMac2)
-        return;
-
-    lout << "- Tracking Thread started..." << endl;
-
-    SlaStars sla(fObservatory);
-    sla.Now();
-
-    ZdAz old;
-    ZdAz ist = GetSePos();              // [se]
-
-    ZdAz time;
-
-    ZdAz sollzd = sla.CalcZdAz(fRaDec); // [rad]
-    ZdAz sollaz = sollzd;               // [rad]
-
-    //
-    // only update fTrackingError while tracking
-    //
-    bool phca1=false;
-    bool phca2=false;
-    bool phcaz=false;
-
-    while (fBackground==kBgdTracking)
-    {
-        //
-        // Make changes (eg wind) smoother - attenuation of control function
-        //
-        const float weight = 1.; //0.3;
-
-        //
-        // This is the time constant which defines how fast
-        // you correct for external influences (like wind)
-        //
-        fZd1->ResetPosHasChanged();
-        fZd2->ResetPosHasChanged();
-        fAz->ResetPosHasChanged();
-        do
-        {
-            phca1 = fZd1->PosHasChanged();
-            phca2 = fZd2->PosHasChanged();
-            phcaz = fAz->PosHasChanged();
-            usleep(1);
-        } while (!phca1 && !phca2 && !phcaz && fBackground==kBgdTracking);
-
-        //---usleep(100000); // 0.1s
-
-        //
-        // get position, where we are
-        //
-        old = ist;
-        ist = GetSePos(); // [se]
-
-        //
-        // if the position didn't change continue
-        //
-        /*---
-         if ((int)ist.Zd() == (int)old.Zd() &&
-         (int)ist.Az() == (int)old.Az())
-         continue;
-         */
-        ZdAz istre = GetRePosPdo();
-
-        //
-        // Get time from last shaftencoder position change (position: ist)
-        // FIXME: I cannot take the avarage
-        //
-        // FIXME
-        //time.Zd(fZd1->GetMjd());
-        /* OLD* */
-        if (fZd1->GetMjd()>fZd2->GetMjd())
-            time.Zd(fZd1->GetMjd());
-        else
-            time.Zd(fZd2->GetMjd());
-
-        //time.Zd((fZd1->GetMjd()+fZd2->GetMjd())/2.0);
-        time.Az(fAz->GetMjd());
-
-        //
-        // if Shaftencoder changed position
-        // calculate were we should be
-        //
-        if (phca1 || phca2 /*(int)ist.Zd() != (int)old.Zd()*/)
-        {
-            sollzd = sla.CalcZdAz(fRaDec, time.Zd()); // [rad]
-            /*
-            ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
-            sollzd = CorrectTarget(ist, dummy); // [se]
-            */
-            fOffset.Zd(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight);
-        }
-
-        if (phcaz /*(int)ist.Az() != (int)old.Az()*/)
-        {
-            sollaz = sla.CalcZdAz(fRaDec, time.Az()); // [rad]
-            /*
-            ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
-            sollaz = CorrectTarget(ist, dummy); // [se]
-            */
-            fOffset.Az(fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight);
-        }
-
-        ZdAz soll(sollzd.Zd(), sollaz.Az()); // [rad]
-
-        fZdAzSoll = AlignTrackingPos(soll);
-
-        ist *= TMath::Pi()*2/16384;
-        soll = fBending(fZdAzSoll);
-        fTrackingError.Set(ist.Zd()-soll.Zd(), ist.Az()-soll.Az());
-
-        //---            fout << setprecision(15) << setw(17) << time.Zd()*60.*60.*24. << " ";
-        //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Zd() << "  ";
-        //---            fout << setprecision(15) << setw(17) << time.Az()*60.*60.*24. << " ";
-        //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Az() << endl;
-    }
-
-    lout << "- Tracking Thread done." << endl;
-
-    //---        fout << endl << endl;
 }
 
@@ -1813,5 +941,5 @@
         }
 
-        Double_t apos = (pos[0]-pos[1])/2 * TMath::Pi()*2 / 16384;
+        Double_t apos = (pos[0]-pos[1])/2 * TMath::TwoPi() / kResSE.X();
 
         ZdAz bend = fBending.CorrectBack(ZdAz(apos, pos[2]))*kRad2Deg;
@@ -1865,5 +993,5 @@
         ZdAz dre = re-re0;
 
-        if (fabs(dse.Zd())*144>16384) // Each 2.5deg (144)
+        if (fabs(dse.Zd())*144>kResSE.X()) // Each 2.5deg (144)
         {
             se0.Zd(se.Zd());
@@ -1872,9 +1000,9 @@
             se -= dse/2;
 
-            ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg;
+            ZdAz bend = fBending.CorrectBack(se*TMath::TwoPi()/kResSE)*kRad2Deg;
             ((TH3*)fHist)->Fill(bend.Zd(), bend.Az(), dre.Zd()/dse.Zd());
         }
 
-        if (fabs(dse.Az())*144>16384) // Each 2.5deg (144)
+        if (fabs(dse.Az())*144>kResSE.Y()) // Each 2.5deg (144)
         {
             se0.Az(se.Az());
@@ -1883,5 +1011,5 @@
             se -= dse/2;
 
-            ZdAz bend = fBending.CorrectBack(se*2*TMath::Pi()/16384)*kRad2Deg;
+            ZdAz bend = fBending.CorrectBack(se*TMath::TwoPi()/kResSE)*kRad2Deg;
             ((TH3*)fHist)->Fill(bend.Az(), bend.Az(), dre.Az()/dse.Az());
         }
@@ -1927,9 +1055,9 @@
         case kBgdNone:
             continue;
-
+/*#ifndef NEWALGO
         case kBgdTracking:
             TalkThreadTracking();
             continue;
-
+#endif*/
         case kBgdSeTest:
             TalkThreadSeTest();
@@ -1952,17 +1080,20 @@
 
     // GetPointingPos [deg]
-    const ZdAz seist = GetSePos()*2*TMath::Pi()/16384; // [se]
-
-    //cout << seist.Zd()*kRad2Deg << " " << seist.Az()*kRad2Deg << endl;
-
-    ZdAz back = fBending.CorrectBack(seist)*180/TMath::Pi();
-
-    //cout << back.Zd() << " " << back.Az() << endl;
-
-    return back;
+    const ZdAz seist = GetSePos()*TMath::TwoPi()/kResSE; // [rad]
+    return fBending.CorrectBack(seist)*TMath::RadToDeg();
 }
 
 Bool_t MCosy::HandleTimer(TTimer *t)
 {
+    const Int_t rc = fMutexGui.TryLock();
+    if (rc==13)
+        cout << "MCosy::HandleTimer - mutex is already locked by this thread" << endl;
+
+    if (rc)
+    {
+        lout << "* GUI update skipped due to locked mutex." << endl;
+        return kTRUE;
+    }
+
     //
     // Update Gui, foremer MTGui.
@@ -1975,6 +1106,4 @@
         fAz->DisplayVal();
 
-    ZdAz bendist = GetPointingPos();
-
     Byte_t avail = 0;
 
@@ -1989,9 +1118,13 @@
         SetStatus(MDriveCom::kError);
 
-    lout.UpdateGui();
-
+    ZdAz bendist = GetPointingPos();
+    fCom->SendReport(fStatus, fRaDec, fZdAzSoll, bendist, fTrackingError);
+
+    fWin->UpdateWeather(*fCom);
     fWin->Update(bendist, fTrackingError, fVelocity, /*fOffset,*/
                  fRaDec, fZdAzSoll, fStatus, avail);
 
+    lout.UpdateGui();
+
     const Bool_t trigger = fTriggerDisplay;
     fTriggerDisplay = kFALSE;
@@ -2003,11 +1136,7 @@
         DisplayHistGear(!trigger);
 
-    // FIXME: Not thread safe!
-    static int i=0;
-    if (i++==7)
-    {
-        fCom->SendReport(fStatus, fRaDec, fZdAzSoll, bendist, fTrackingError);
-        i=0;
-    }
+    if (fMutexGui.UnLock()==13)
+        cout << "MCosy::HandleTimer - tried to unlock mutex locked by other thread." << endl;
+
     return kTRUE;
 }
@@ -2195,4 +1324,8 @@
     fAz =new ShaftEncoder(id6, "SE/Az",  lout);
 
+    fZd1->SetReport(fOutRep);
+    fZd2->SetReport(fOutRep);
+    fAz->SetReport(fOutRep);
+
     lout << "- Connecting devices to network." << endl;
 
@@ -2265,6 +1398,23 @@
 }
 */
+
+TString MCosy::GetFileName(const char *fmt)
+{
+    // FIXME: Timeout missing
+    while (1)
+    {
+        MTime time(-1);
+        const TString name = Form(fmt, (const char*)time.GetFileName());
+        if (gSystem->AccessPathName(name, kFileExists))
+            return name;
+            break;
+
+        usleep(1000);
+    }
+    return "";
+}
+
 MCosy::MCosy(/*int mode,*/ const char *dev, const int baud, MLog &out)
-: Network(dev, baud, out), fObservatory(MObservatory::kMagic1), fStarguider(NULL), fZd1(0), fZd2(0), fAz(0), fMac1(0), fMac2(0), fMac3(0), fBackground(kBgdNone), fStatus(MDriveCom::kStopped)
+: Network(dev, baud, out), fObservatory(MObservatory::kMagic1), fStarguider(NULL), fZd1(0), fZd2(0), fAz(0), fMac1(0), fMac2(0), fMac3(0), fBackground(kBgdNone), fStatus(MDriveCom::kStopped), fOutTp(0), fOutRep(0)
 {
     TEnv env(".cosyrc");
@@ -2275,4 +1425,9 @@
     const Int_t id5 = env.GetValue("Zd_Id-SE2",  5); //5
     const Int_t id6 = env.GetValue("Az_Id-SE",   6); //6
+
+    TString name = GetFileName("rep/cosy_%s.rep");
+    cout << "Open Repfile: " << name << endl;
+    fOutRep = new MLog(name, kTRUE);
+
 /*
     lout << "- Program in ";
@@ -2300,28 +1455,5 @@
     fAz->SetDisplay(fWin->GetLabel1());
 
-    //
-    // open tpoint file
-    //
-    MTime time;
-    TString name;
-    while (1)
-    {
-        time.Now();
-        name = Form("tpoint/tpoint_%s.txt", (const char*)time.GetFileName());
-        if (gSystem->AccessPathName(name, kFileExists))
-            break;
-    }
-
-    cout << "TPoint File ********* " << name << " ********** " << endl;
-
-    tpout = new ofstream(name);
-    *tpout << "Magic Model  TPOINT data file" << endl;
-    *tpout << ": ALTAZ" << endl;
-    *tpout << "49 48 0 ";
-    *tpout << time.Year() << " " << time.Month() << " " << time.Day() << " ";
-    *tpout << /*"20 1013.25 300 0.5 0.55 0.0065" <<*/ endl;
-    // temp(°C) pressure(mB) height(m) humidity(1) wavelength(microm) troplapserate(K/m)
-
-    fCom = new MDriveCom(this, out);
+    fCom = new MDriveCom(this, *fOutRep);
     fCom->Start();
 }
@@ -2349,7 +1481,10 @@
 MCosy::~MCosy()
 {
-    *tpout << "END" << endl;
-    //streampos size = tpout.tellp();
-    delete tpout;
+    if (fOutTp)
+    {
+        *fOutTp << "END" << endl;
+        delete fOutTp;
+    }
+    delete fOutRep;
 
     cout << "Deleting GUI timer." << endl;
@@ -2359,4 +1494,8 @@
 
     cout << "Deleting Nodes." << endl;
+
+    fZd1->SetReport(0);
+    fZd2->SetReport(0);
+    fAz->SetReport(0);
 
     delete fAz;
Index: trunk/MagicSoft/Cosy/main/MCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/main/MCosy.h	(revision 4076)
@@ -8,6 +8,9 @@
 #include "MBending.h"
 
-#ifndef MARS_Mobservatory
+#ifndef MARS_MObservatory
 #include "MObservatory.h"
+#endif
+#ifndef ROOT_TMutex
+#include <TMutex.h>
 #endif
 
@@ -62,4 +65,6 @@
 {
     friend class MTTalk;
+    friend class MPointing;
+    friend class MTracking;
 
 private:
@@ -83,8 +88,10 @@
                           // with a generic interface to both...
 
+    TMutex fMutexGui;
+
     enum BackgroundAction_t
     {
         kBgdNone,
-        kBgdTracking,
+        //kBgdTracking,
         kBgdSeTest,
         kBgdSeTestDispl,
@@ -96,5 +103,4 @@
 
     ZdAz  fTrackingError; // [rad] Tracking Offset between SE and calc-pos
-    ZdAz  fOffset;        // Offset between se and re coordinate system [re]
     ZdAz  fZdAzSoll;      // [rad] Soll position when moving
     RaDec fRaDec;         // Position to track
@@ -107,6 +113,8 @@
     Bool_t fTriggerDisplay;
 
-    XY kGearRatio;        // describing the gear of the system [re/se]
-    XY kGearRatio2;       // describing the gear of the system [re/deg]
+    XY kResSE;   // describing the resolution of the system [se/U_tel]
+    XY kResRE;   // describing the resolution of the system [re/U_mot]
+    XY kGear;    // describing the resolution of the system [U_mot/U_tel]
+    XY kGearTot; // describing the resolution of the system [re/U_tel]
 
     MBending fBending;
@@ -114,17 +122,11 @@
     UInt_t fStatus;
 
-    ofstream *tpout;
-
-    //Bool_t AlignTrackingPos(ZdAz pointing, ZdAz &za) const;
+    ofstream *fOutTp;
+    MLog     *fOutRep;
+
     ZdAz AlignTrackingPos(ZdAz pointing) const;
     Bool_t CheckRange(const ZdAz &d) const;
     Double_t Starguider(Double_t mjd, ZdAz &dest) const;
 
-    double Rad2SE(double rad) const;
-    double Rad2ZdRE(double rad) const;
-    double Rad2AzRE(double rad) const;
-    double Deg2ZdRE(double rad) const;
-    double Deg2AzRE(double rad) const;
-
     void SetStatus(UInt_t stat) { fStatus = stat; }
     UInt_t GetStatus() const { return fStatus; }
@@ -133,18 +135,10 @@
     ZdAz GetRePosPdo();
     ZdAz GetSePos() const; // [se]
-
-    Bool_t RequestRePos();
-    Bool_t SetVelocity(const ZdAz &v);
-
-    void SetPosVelocity(const Float_t ratio, Float_t vel);
-
-    void DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2);
+    // FIXME: Must depend on the Shaftencoder mounted
+    ZdAz GetSePosRad() const { return GetSePos()*TMath::TwoPi()/16384; } // [rad]
 
     void InitSync();
-    bool InitTracking();
-    Bool_t LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const;
 
     void TalkThread();
-    void TalkThreadTracking();
     void TalkThreadSeTest();
     void TalkThreadGear();
@@ -154,8 +148,7 @@
 
     int  SetPosition(const ZdAz &dst, Bool_t track=kFALSE);
+    void TrackPosition(const RaDec &dst); // ra, dec [rad]
 
     void TerminateApp();
-
-    void TrackPosition(const RaDec &dst); // ra, dec [rad]
 
     int StopWaitingForSDO() const;
@@ -163,5 +156,4 @@
 
     void StopMovement();
-    void StopTracking();
 
     void WaitForEndMovement();
@@ -188,5 +180,17 @@
     ZdAz GetPointingPos(void) const;
     void SetStarguider(MStarguider *s) { fStarguider = s; }
-  
+
+    static TString GetFileName(const char *name);
+
+    MGCosy *GetWin() { return fWin; }
+
+    AltAz GetAltAzDeg() const
+    {
+        ZdAz sepos = GetSePos()*TMath::TwoPi()/kResSE;
+        AltAz za1(TMath::Pi()/2-sepos.Zd(), sepos.Az());
+        za1 *= kRad2Deg;
+        return za1;
+    }
+
     // static ZdAz CorrectTarget(const ZdAz &src, const ZdAz &dst);
     //    static ZdAz RaDec2ZdAz(const double mjd, const RaDec &pos, const RaDec &pm=RaDec(0,0));
Index: trunk/MagicSoft/Cosy/main/MPointing.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MPointing.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/main/MPointing.cc	(revision 4076)
@@ -74,5 +74,5 @@
     const int vr = mac->GetVelRes();
     mac->SetAcceleration(acc*vr);
-    mac->SetAcceleration(dec*vr);
+    mac->SetDeceleration(dec*vr);
     return !mac->IsZombieNode();
 }
@@ -96,5 +96,4 @@
 int MPointing::SetPosition(const ZdAz &dst, Bool_t track) // [rad]
 {
-    /*
     const ZdAz d = dst*kRad2Deg;
 
@@ -105,5 +104,5 @@
     // Calculate new target position (shortest distance to go)
     //
-    const ZdAz src = fCosy->GetSePos(); // [se]
+    //const ZdAz src = fCosy->GetSePos(); // [se]
 
     //
@@ -123,5 +122,5 @@
     ZdAz bend = fCosy->fBending(dst); // [rad]
 
-    const ZdAz dest = bend*16384/2/TMath::Pi(); // [se]
+    const ZdAz dest = bend*fCosy->kResSE/TMath::TwoPi(); // [se]
 
     if (!fCosy->CheckRange(bend))
@@ -131,46 +130,35 @@
     fCosy->fZdAzSoll = dst;
 
-    cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
-    cout << "Destination   Zd: " << dst.Zd()*8192/TMath::Pi() << "se  Az:" << dst.Az()*8192/TMath::Pi()  << "se" << endl;
-    cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
-    cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
+    //cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
+    //cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
+    //cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
+    //cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
+
+    //
+    // Set velocities
+    //
+    //const int vr = fCosy->fMac1->GetVelRes();
+
+    const Float_t rad2se = fCosy->kResSE.X()/TMath::TwoPi();
 
     int i;
-    for (i=0; i<(track?1:10) && !Break(); i++)
+    for (i=0; i<(track?1:10) && !Break()/*(fCosy->Break() || fCosy->HasError() || fCosy->HasZombie())*/; i++)
     {
 
         lout << "- Step #" << i << endl;
-        //
+
         // Get Shaft Encoder Positions
-        //
         const ZdAz p=fCosy->GetSePos();
 
-        //
         // calculate control deviation and rounded cd
-        //
         ZdAz rd = dest-p; // [se]
-
-        // ===========================================
-        const ZdAz ist = dst-rd*TMath::Pi()/8192;
-
-        const double p1 = ist.Zd()-19.0605/kRad2Deg;
-        const double p2 = dst.Zd()-19.0605/kRad2Deg;
-
-        const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*8192/TMath::Pi();
-        const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*8192/TMath::Pi();
-        // ===========================================
-
         ZdAz cd = rd;     // [se]
         cd.Round();
 
-        //
         // Check if there is a control deviation on the axis
-        //
         const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
         const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
 
-        //
         // check if we reached the correct position already
-        //
         if (!cdzd && !cdaz)
         {
@@ -178,207 +166,25 @@
             lout << t << " - Positioning done in " << i << (i==1?" step.":" steps.") << endl;
             fCosy->SetStatus(MDriveCom::kStopped);
-            fCosy->fCom->Send("POSITION DONE");
+            fCosy->fCom->SendStatus("Target position reached.");
             return TRUE;
         }
 
-        //
+        // ==============================================
+        //   Estimate the noncircularity of the zd axis
+        const ZdAz ist = dst-rd*TMath::TwoPi()/fCosy->kResSE;
+
+        const double p1 = ist.Zd()-19.0605/kRad2Deg;
+        const double p2 = dst.Zd()-19.0605/kRad2Deg;
+
+        const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*rad2se;
+        const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*rad2se;
+        // ==++=========================================
+
         // change units from se to re
-        //
-        rd *= fCosy->kGearRatio; // [re]
+        rd *= fCosy->kGearTot/fCosy->kResSE; // [re]
         rd.Zd(f2-f1);
 
-        //
         // Initialize Velocities so that we reach both positions
         // at the same time
-        //
-        if (i)
-        {
-            lout << "--- LO-SPEED ---" << endl;
-            SetAccDec(fCosy->fMac1, 0.1, 0.1);
-            SetAccDec(fCosy->fMac2, 0.1, 0.1);
-
-            SetPosVelocity(1.0, 0.05);
-        }
-        else
-        {
-            const Double_t y = 15*fCosy->kGearRatio.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);
-
-            SetAccDec(fCosy->fMac2, fAcc, fDec);
-
-            SetPosVelocity(fabs(rd.Ratio()), fVel);
-        }
-
-        rd.Round();
-
-        // FIXME? Check for Error or Zombie?
-
-        // cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
-        // cout << " + APOS:  Zd=" << setw(6) << p.Zd()  << "se   Az=" << setw(6) << p.Az()  << "se" << endl;
-        // cout << " +       dZd=" << setw(6) << cd.Zd() << "se  dAz=" << setw(6) << cd.Az() << "se" << endl;
-        // cout << " +       dZd=" << setw(6) << rd.Zd() << "re  dAz=" << setw(6) << rd.Az() << "re" << endl;
-        // cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X()  << "se   Az=" << setw(6) << kGearRatio.Y()  << "se" << endl;
-
-        //
-        // repositioning (relative)
-        //
-
-        lout << "- Do Relative Positioning..." << endl;
-        DoRelPos(rd, cdzd, cdaz);
-        lout << "- Relative Positioning Done" << endl;
-    }
-
-
-    return FALSE;*/
-
-    const ZdAz d = dst*kRad2Deg;
-
-    MTime t(-1);
-    lout << t << " - Target Position: " << d.Zd() << "deg, " << d.Az() << "deg (Zd/Az)" << endl;
-
-    //
-    // Calculate new target position (shortest distance to go)
-    //
-    //const ZdAz src = fCosy->GetSePos(); // [se]
-
-    //
-    // Make sure that the motors are in sync mode (necessary if the
-    // MACS has been rebooted from a Zombie state.
-    //
-    //InitSync();
-    //if (fMac3->IsZombieNode())
-    //    return false;
-
-    //
-    // Because we agreed on I don't search for the shortest move
-    // anymore
-    //
-    // const ZdAz dest = CorrectTarget(src, dst);
-    //
-    ZdAz bend = fCosy->fBending(dst); // [rad]
-
-    const ZdAz dest = bend*16384/2/TMath::Pi(); // [se]
-
-    if (!fCosy->CheckRange(bend))
-        return kFALSE;
-
-    bend *= kRad2Deg;
-    fCosy->fZdAzSoll = dst;
-
-    //cout << "Source        Zd: " << src.Zd()  << "se  Az:" << src.Az()  << "se" << endl;
-    //cout << "Destination   Zd: " << Rad2SE(dst.Zd()) << "se  Az:" << Rad2SE(dst.Az())  << "se" << endl;
-    //cout << "Bend'd Dest   Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
-    //cout << "Bend'd Dest   Zd: " << bend.Zd() << "deg  Az:" << bend.Az() << "deg" << endl;
-
-    //
-    // Set velocities
-    //
-    //const int vr = fCosy->fMac1->GetVelRes();
-
-    int i;
-    for (i=0; i<(track?1:10) && !Break()/*(fCosy->Break() || fCosy->HasError() || fCosy->HasZombie())*/; i++)
-    {
-
-        lout << "- Step #" << i << endl;
-        //
-        // Get Shaft Encoder Positions
-        //
-        const ZdAz p=fCosy->GetSePos();
-
-        //
-        // calculate control deviation and rounded cd
-        //
-        ZdAz rd = dest-p; // [se]
-
-        // ===========================================
-        const ZdAz ist = dst-rd*TMath::Pi()/8192;
-
-        const double p1 = ist.Zd()-19.0605/kRad2Deg;
-        const double p2 = dst.Zd()-19.0605/kRad2Deg;
-
-        const double f1 = (-26.0101*sin(p1)+443.761*ist.Zd())*8192/TMath::Pi();
-        const double f2 = (-26.0101*sin(p2)+443.761*dst.Zd())*8192/TMath::Pi();
-        // ===========================================
-
-        ZdAz cd = rd;     // [se]
-        cd.Round();
-
-        //
-        // Check if there is a control deviation on the axis
-        //
-        const Bool_t cdzd = (int)cd.Zd() ? kTRUE : kFALSE;
-        const Bool_t cdaz = (int)cd.Az() ? kTRUE : kFALSE;
-
-        //
-        // check if we reached the correct position already
-        //
-        if (!cdzd && !cdaz)
-        {
-            t.Now();
-            lout << t << " - Positioning done in " << i << (i==1?" step.":" steps.") << endl;
-            fCosy->SetStatus(MDriveCom::kStopped);
-            fCosy->fCom->Send("POSITION DONE");
-            return TRUE;
-        }
-
-        //
-        // change units from se to re
-        //
-        rd *= fCosy->kGearRatio; // [re]
-        rd.Zd(f2-f1);
-
-        //
-        // Initialize Velocities so that we reach both positions
-        // at the same time
-        //
-/*        if (i)
-        {
-            fCosy->fMac1->SetAcceleration(0.1*vr);
-            fCosy->fMac2->SetAcceleration(0.1*vr);
-
-            fCosy->fMac1->SetDeceleration(0.1*vr);
-            fCosy->fMac2->SetDeceleration(0.1*vr);
-
-            fCosy->SetPosVelocity(1.0, 0.05);
-        }
-        else
-        {
-            if (rd.Az()>-15*fCosy->kGearRatio.Y() && rd.Az()<15*fCosy->kGearRatio.Y())
-            {
-#ifdef EXPERT
-                cout << " -------------- LO ---------------- " << endl;
-#endif
-                fCosy->fMac1->SetAcceleration(0.05*vr);
-                fCosy->fMac1->SetDeceleration(0.05*vr);
-            }
-            else
-            {
-#ifdef EXPERT
-                cout << " -------------- HI ---------------- " << endl;
-                fCosy->fMac1->SetAcceleration(0.4*vr);// 0.4
-                fCosy->fMac1->SetDeceleration(0.4*vr);// 0.4
-#else
-                fCosy->fMac1->SetAcceleration(0.2*vr);
-                fCosy->fMac1->SetDeceleration(0.1*vr);
-#endif
-            }
-
-#ifdef EXPERT
-            fCosy->fMac2->SetAcceleration(0.4*vr);// 0.4
-            fCosy->fMac2->SetDeceleration(0.4*vr);// 0.4
-            fCosy->SetPosVelocity(fabs(rd.Ratio()), 0.2); // fast: 0.6, slow: 0.2
-#else
-            fCosy->fMac2->SetAcceleration(0.2*vr);
-            fCosy->fMac2->SetDeceleration(0.1*vr);
-            fCosy->SetPosVelocity(fabs(rd.Ratio()), 0.1);
-#endif
-        }
-        */
         if (i)
         {
@@ -391,5 +197,5 @@
         else
         {
-            const Double_t y = 15*fCosy->kGearRatio.Y();
+            const Double_t y = 15*fCosy->kGearTot.Y()*fCosy->kResSE.Y();
             if (rd.Az()>-y && rd.Az()<y)
             {
@@ -409,5 +215,4 @@
         // FIXME? Check for Error or Zombie?
 
-
         // cout << " + " << (int)cdzd << " " << (int)cdaz << endl;
         // cout << " + APOS:  Zd=" << setw(6) << p.Zd()  << "se   Az=" << setw(6) << p.Az()  << "se" << endl;
@@ -416,8 +221,5 @@
         // cout << " + Ratio: Zd=" << setw(6) << kGearRatio.X()  << "se   Az=" << setw(6) << kGearRatio.Y()  << "se" << endl;
 
-
-        //
         // repositioning (relative)
-        //
         lout << "- Do Relative Positioning..." << endl;
         DoRelPos(rd, cdzd, cdaz);
@@ -429,5 +231,5 @@
         lout << t << " - Positioning done." << endl;
         fCosy->SetStatus(MDriveCom::kStopped);
-        fCosy->fCom->Send("POSITION DONE");
+        fCosy->fCom->SendStatus("Tracking preposition reached.");
         return TRUE;
     }
@@ -441,5 +243,5 @@
     lout << t << " - Warning: Requested position not reached (i=" << dec << i << ")" << endl;
 
-    fCosy->fCom->Send("POSITION FAILED");
+    fCosy->fCom->SendStatus("Target position missed!");
 
     return FALSE;
Index: trunk/MagicSoft/Cosy/main/MTracking.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MTracking.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/main/MTracking.cc	(revision 4076)
@@ -13,4 +13,40 @@
 //#define EXPERT
 #undef EXPERT
+
+// --------------------------------------------------------------------------
+//
+// request the current positions from the rotary encoders.
+// use GetRePos to get the psotions. If the request fails the function
+// returns kFALSE, otherwise kTRUE
+//
+bool MTracking::RequestRePos()
+{
+    //
+    // Send request
+    //
+    fCosy->fMac2->RequestSDO(0x6004);
+    fCosy->fMac1->RequestSDO(0x6004);
+
+    //
+    // Wait until the objects are received.
+    //
+    fCosy->fMac2->WaitForSdo(0x6004);
+    fCosy->fMac1->WaitForSdo(0x6004);
+
+    //
+    // If waiting was not interrupted everything is ok. return.
+    //
+    if (!Break())
+        return true;
+
+    //
+    // If the waiting was interrupted due to a network error,
+    // print some logging message.
+    //
+    if (fCosy->HasError())
+        lout << "Error while requesting re pos from Macs (SDO #6004)" << endl;
+
+    return false;
+}
 
 // --------------------------------------------------------------------------
@@ -49,5 +85,46 @@
     return true;
 }
-
+/*
+void MTracking::StopTracking()
+{
+    //
+    // Set status to Stopping
+    //
+    fCosy->SetStatus(MDriveCom::kStopping);
+
+    //
+    // set deceleration to 50%
+    //
+    cout << "Stopping tracking (dec=20%)..." << endl;
+    fCosy->fMac1->SetDeceleration(0.2*fMac1->GetVelRes());
+    fCosy->fMac2->SetDeceleration(0.2*fMac2->GetVelRes());
+
+    fCosy->fMac2->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
+    fCosy->fMac1->SendSDO(0x3006, 1, (LWORD_t)0);  // SetRpmVelocity [re/min]
+    fCosy->fMac2->WaitForSdo(0x3006, 1);
+    fCosy->fMac1->WaitForSdo(0x3006, 1);
+
+    cout << "Waiting for end of movement..." << endl;
+    fCosy->WaitForEndMovement();
+
+    //
+    // Wait for the objects to be OKed.
+    //
+    fCosy->fMac1->SetRpmMode(FALSE);
+    fCosy->fMac2->SetRpmMode(FALSE);
+
+    //
+    // Wait for the movement to really be finished.
+    //
+    //cout << "Waiting for end of movement..." << endl;
+    //WaitForEndMovement();
+
+    //
+    // Check whether everything works fine.
+    //
+    fCosy->CheckForError();
+    cout << "Movement stopped." << endl;
+}
+*/
 // --------------------------------------------------------------------------
 //
@@ -58,6 +135,18 @@
 // velocities are limited to the maximum velocity.
 //
-Bool_t MTracking::LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const
-{
+Bool_t MTracking::LimitSpeed(ZdAz *vt, const SlaStars &sla) const
+{
+    // vt[re/min]
+
+    // Calculate approximate velocity of both axis
+    ZdAz vcalc = sla.GetApproxVel(fCosy->fRaDec);  // [rad/rad]
+
+    //vcalc *= 1./(24*60);          // [U_tel/min]
+    //vcalc *= fCosy->kGearTot; // [U_mot/min]
+    //vcalc *= fCosy->kResRE;   // [re/min]
+
+    vcalc *= fCosy->kGearTot*fCosy->kResRE/(24*60); // [re/min]
+
+    // Set return code
     Bool_t rc = kFALSE;
 
@@ -83,14 +172,16 @@
     const Float_t maxtrack = 0.1;
 
-    if (fabs(vt->Az()) > maxtrack*vraz)
-    {
+    if (fabs(vt->Az()) > maxtrack*vraz*4)
+    {
+        vt->Az(maxtrack*vraz*4*sgn(vcalc.Az()));
         lout << "Warning: Azimuth speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Az()) << " > " << maxtrack*vraz << ")... limited." << endl;
-        vt->Az(maxtrack*vraz*sgn(vcalc.Az()));
+        lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
         rc=kTRUE;
     }
-    if (fabs(vt->Zd()) > maxtrack*vrzd)
-    {
+    if (fabs(vt->Zd()) > maxtrack*vrzd*4)
+    {
+        vt->Zd(maxtrack*vrzd*4*sgn(vcalc.Zd()));
         lout << "Warning: Altitude speed limit (" << maxtrack*100 << "%) exceeded (" << fabs(vt->Zd()) <<" > " << maxtrack*vrzd << ")... limited." << endl;
-        vt->Zd(maxtrack*vrzd*sgn(vcalc.Zd()));
+        lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
         rc=kTRUE;
     }
@@ -146,27 +237,19 @@
     lout << sla.GetTime() << ": Track Position " << dst.Ra()*kRad2Deg/15 << "h, " << dst.Dec()*kRad2Deg <<"deg" << endl;
 
-    // az between -180 and 180
-    if (dst.Dec()>sla.GetPhi() && dest.Az()<0)
-    {
-        // align az between (roughly) 60 and 320
-        lout << "Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
-        dest.Az(dest.Az() + TMath::Pi()*2);
-    }
-/*
-    // FIXME: Determin tracking start point by star culmination
-    if (dest.Az()<-TMath::Pi()/2)
-    {
-        lout << "Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
-        dest.Az(dest.Az() + TMath::Pi()*2);
-    }
-
-    if (dest.Az()>3*TMath::Pi()/2)
-    {
-        lout << "Substracting 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
-        dest.Az(dest.Az() -TMath::Pi()*2);
-    }
- */
+    // If the star is culminating behind the zenith (South) we want to
+    // align the azimuth angle between -180 and 180deg. If the star is
+    // culminating before the zenith (north) we want the star to be
+    // aligned between -180 and 180deg (which is the default of CalcZdAz)
+    if (sla.GetPhi()>dst.Dec() && dest.Az()<0)
+    {
+        // align az from -180/180 to 0/360
+        lout << "Star culminating behind zenith: Adding 360deg to Azimuth " << dest.Az()*kRad2Deg << endl;
+        dest.Az(dest.Az() + TMath::TwoPi());
+    }
+
+    // Position the telescope to the current local position of the
+    // star. Do not reposition but start the tracking after the
+    // first positioning step
     if (!SetPosition(dest, kTRUE))
-    //if (!SetPosition(dest, kFALSE))
     {
         lout << "Error: Cannot start tracking, positioning failed." << endl;
@@ -177,7 +260,6 @@
     // calculate offset from present se position
     //
-    const ZdAz sepos = fCosy->GetSePos()*fCosy->kGearRatio;
-
-    if (!fCosy->RequestRePos())
+    const ZdAz sepos = fCosy->GetSePos()*fCosy->kGearTot/fCosy->kResSE; //[re]
+    if (!RequestRePos())
         return;
 
@@ -185,5 +267,5 @@
     // Estimate Offset before starting to track
     //
-    fCosy->fOffset = sepos-fCosy->GetRePos();
+    fOffset = sepos-fCosy->GetRePos();
 
     /*
@@ -202,18 +284,5 @@
     }
 
-    XY xy(Rad2Deg(dst.Ra())*24/360, Rad2Deg(dst.Dec()));
-
-    sla.Now();
-//    lout << sla.GetTime() << " - Start tracking:";
-//    lout << " Ra: " << xy.X() << "h  " << "Dec: " << xy.Y() << "\xb0" << endl;
-
-/*#ifdef EXPERT
-    ofstream fout("coordinates.txt");
-    fout << xy;
-    fout.close();
-#endif
-*/    //
     // Initialize Tracker (slalib or starguider)
-    //
     fCosy->fRaDec = dst;
 
@@ -221,14 +290,12 @@
     Start();
 
+    // Get current nominal local position
+    sla.Now();
     ZdAz pos = sla.CalcZdAz(fCosy->fRaDec);
 
+    // Some output
+    XY xy(Rad2Deg(dst.Ra())*24/360, Rad2Deg(dst.Dec()));
     lout << sla.GetTime() << " - Start Tracking: Ra=" <<xy.X() << "h Dec=";
     lout << xy.Y() << "\xb0 @ Zd=" << pos.Zd()*kRad2Deg <<"deg Az=" << pos.Az()*kRad2Deg <<"deg" << endl;
-
-//---    ofstream fout("log/cosy.pos");
-//---    fout << "Tracking:";
-//---    fout << " Ra: " << Rad2Deg(dst.Ra())  << "\x9c  ";
-//---    fout << "Dec: " << Rad2Deg(dst.Dec()) << "\x9c" << endl << endl;
-//---    fout << "     Mjd/10ms    V/re/min/4" << endl;
 
     //
@@ -240,26 +307,16 @@
     {
         //
-        // Request Target position for this moment
+        // Request Target position for Now+dt
         //
         sla.Now(dt);
 
         //
-        // Request theoretical Position for a time in the future (To+dt) from CPU
-        //
-        const ZdAz pointing = sla.CalcZdAz(fCosy->fRaDec); // soll pointing [rad]
-
-        //lout << sla.GetTime() << pointing.Zd()*kRad2Deg << " " << pointing.Az()*kRad2Deg << endl;
-        /*
-        ZdAz dest;
-        if (!AlignTrackingPos(pointing, dest))
-            break;
-            */
-        ZdAz dest = fCosy->AlignTrackingPos(pointing);
-
-        // lout << "DEST: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
-
-        ZdAz vcalc = sla.GetApproxVel(fCosy->fRaDec) * fCosy->kGearRatio2*4./60.;
-        //lout << "Vcalc: " << dest.Zd() << " " << dest.Az() << endl;
-        vcalc *= fCosy->kGearRatio2*4./60.; // [re/min]
+        // Request nominal position for this time in the future (To+dt)
+        //
+        const ZdAz pointing = sla.CalcZdAz(fCosy->fRaDec); // [rad]
+        ZdAz dest = fCosy->AlignTrackingPos(pointing);     // fix ambiguity
+
+        //ZdAz vcalc = sla.GetApproxVel(fCosy->fRaDec);
+        //vcalc *= fCosy->kGearRatio2*4./60.; // [re/min]
 
         float dtime = -1;
@@ -267,25 +324,22 @@
         //    dtime = Starguider(sla.GetMjd(), dest);
 
+        ZdAz repos;
         if (dtime<0)
         {
-            dest = fCosy->fBending(dest);       // [rad]
-
-            //lout << "DEST-BEND: " << dest.Zd()*kRad2Deg << " " <<dest.Az()*kRad2Deg << endl;
-              
+            dest = fCosy->fBending(dest);            // [rad]
             if (!fCosy->CheckRange(dest))
                 break;
 
-            dest *= 16384/TMath::Pi()/2; // [se]
-            dest *= fCosy->kGearRatio;          // [re]
-
-            *fCosy->fOutRep << "> ReqRePos1 " << endl;
+            dest *= fCosy->kGearTot/TMath::TwoPi();  // [re]
+
+            //*fCosy->fOutRep << "> ReqRePos1 " << endl;
 
             //
             // Request absolute position of rotary encoder from Macs
             //
-            if (!fCosy->RequestRePos())
+            if (!RequestRePos())
                 break;
 
-            *fCosy->fOutRep << "> ReqRePos2 " << endl;
+            //*fCosy->fOutRep << "> ReqRePos2 " << fOffset.Zd() << " " << fOffset.Az() << endl;
 
             //
@@ -294,13 +348,8 @@
             // fOffset does the synchronization between the
             // Shaft- and the rotary encoders
-            dest -= fCosy->GetRePos() + fCosy->fOffset;
+            repos = fCosy->GetRePos();
+            dest -= repos + fOffset; //[re]
 
             dtime = dt;
-
-            ZdAz repos = fCosy->GetRePos();
-    //        lout << "Repos: " << repos.Zd()/kGearRatio.X() << " " << repos.Az()*kGearRatio.Y() << endl;
-   //         repos /= kGearRatio;
-            repos /= 16384/TMath::Pi()/2;
-            repos *= kRad2Deg;
         }
 
@@ -309,5 +358,22 @@
         // correct for the duration of RaDec2AltAz
         //
-        const ZdAz v = dest*60.0/(dtime/*-(fMac2->GetTime()-sla)*/);
+        /* --- OLD --- */
+        ZdAz v = dest*60.0/dtime; //[re/min]
+        /* --- NEW --- seems to work worse! */
+        //const Double_t dtaz = sla.GetTime() - fCosy->fMac1->GetPosTime();
+        //const Double_t dtzd = sla.GetTime() - fCosy->fMac2->GetPosTime();
+        //
+        //ZdAz v = dest*60.0;
+        //v.Zd(v.Zd()/dtzd);
+        //v.Az(v.Az()/dtaz);
+        /* --- END --- */
+
+        //*fCosy->fOutRep << "> Dt:  " << dtaz << "  " << dtzd << endl;
+
+        if (LimitSpeed(&v, sla))
+        {
+            lout << "vt: " << v.Zd() << " " << v.Az() << "re/min" << endl;
+            lout << "Dest: " << dest.Zd() << " " << dest.Az() << endl;
+        }              
 
         //
@@ -315,12 +381,8 @@
         // believing the Macs manual '/4' shouldn't be necessary, but it is.
         //
-        ZdAz vt = v/4;
-        if (LimitSpeed(&vt, vcalc))
-        {
-            lout << "Vcalc: " << vcalc.Zd() << " " << vcalc.Az() << "re/min" <<endl;
-            lout << "vt: " << vt.Zd() << " " << vt.Az() << "re/min" << endl;
-            lout << "Dest: " << dest.Zd() << " " << dest.Az() << endl;
-        }              
+        ZdAz vt = v/4; //[re'/min]
+        //lout << " " << vt.Zd() << " " << vt.Az() << " ";
         vt.Round();
+        //lout << " " << vt.Zd() << " " << vt.Az() << endl;
 
         //
@@ -337,24 +399,21 @@
         // Maybe we should attenuate the changes
         //
-        *fCosy->fOutRep << "> SetVelocity1 " << endl;
+        //*fCosy->fOutRep << "> SetVelocity1:  " << vt.Zd() << "  " << vt.Az() << endl;
         if (!SetVelocity(vt))
             break;
-        *fCosy->fOutRep << "> SetVelocity2 " << endl;
-
-        //
-        // Now do 'unnecessary' things
-        //
-        fCosy->fVelocity = vt/fCosy->kGearRatio2*4;
-
-//---        const double mjd = fMac2->GetMjd();
-//---        fout << setprecision(15) << setw(17) << mjd*60.*60.*24. << " ";
-//---        fout << setw(4) << vt.Zd() << " ";
-//---        fout << setw(4) << vt.Az() << endl;
-        //
-        // FIXME? Calculate an accuracy for the tracking system?
-        // How good do we reach the calculated position in 'real'
-        // re valus?
-        //
-
+        //*fCosy->fOutRep << "> SetVelocity2 " << endl;
+
+        //
+        // Now do 'unnecessary' things (timing)
+        //
+        fCosy->fVelocity = vt*4/fCosy->kGear; // [U_mot/min]
+        // *OLD* fVelocity = vt/kGearRatio2*4;
+
+        if (fOut)
+        {
+            fOut->Lock();
+            *fOut << "RE-REPORT " << MTime(-1) << " " << repos.Zd() << " " << repos.Az() <<" " << vt.Zd() << " " << vt.Az() << endl;
+            fOut->UnLock();
+        }
 
         //
@@ -363,17 +422,10 @@
         // update time
         //
-        //
         // The loop should not be executed faster than the ramp of
         // a change in the velocity can be followed.
         // (This is important on fast machines >500MHz)
         //
-        /*
-        MTimeout t(1000);
-        while (!t.HasTimedOut())
-            usleep(1);
-         */
         usleep(1000000); // 1s
-        cout << "." << flush;
-        //usleep(50000); // 0.05s
+// *****FIXME****        cout << "." << flush;
     }
 
@@ -385,5 +437,7 @@
     fCosy->StopMovement();
 
-    lout << sla.GetTime() << " - Tracking stopped." << endl;
+    lout << sla.GetTime() << " - Tracking stopped @ Zd=";
+    lout << fCosy->fZdAzSoll.Zd()*TMath::RadToDeg() <<"deg Az=";
+    lout << fCosy->fZdAzSoll.Az()*TMath::RadToDeg() <<"deg" << endl;
 }
 
@@ -401,14 +455,12 @@
     lout << "- Tracking Thread started..." << endl;
 
+    const XY re2se = fCosy->kGearTot/fCosy->kResSE; //[re/se]
+
     SlaStars sla(fCosy->fObservatory);
     sla.Now();
 
-    ZdAz old;
-    ZdAz ist = fCosy->GetSePos();              // [se]
-
     ZdAz time;
 
-    ZdAz sollzd = sla.CalcZdAz(fCosy->fRaDec); // [rad]
-    ZdAz sollaz = sollzd;               // [rad]
+    ZdAz soll = sla.CalcZdAz(fCosy->fRaDec); // [rad]
 
     //
@@ -421,18 +473,15 @@
     while (!HasStopFlag())
     {
-        //
         // Make changes (eg wind) smoother - attenuation of control function
-        //
-        const float weight = 1.; //0.3;
-
-        //
         // This is the time constant which defines how fast
         // you correct for external influences (like wind)
-        //
-        *fCosy->fOutRep << "> ResetPosHasChanged" << endl;
+        const float weight = 1.; //0.3;
+
+        // Check for changes of the shaftencoder values
+        //*fCosy->fOutRep << "> ResetPosHasChanged" << endl;
         fCosy->fZd1->ResetPosHasChanged();
         fCosy->fZd2->ResetPosHasChanged();
         fCosy->fAz->ResetPosHasChanged();
-        *fCosy->fOutRep << "> Check for PosHasChanged" << endl;
+        //*fCosy->fOutRep << "> Check for PosHasChanged" << endl;
         do
         {
@@ -443,31 +492,16 @@
         } while (!phca1 && !phca2 && !phcaz && !HasStopFlag());
 
-        //---usleep(100000); // 0.1s
-
-        *fCosy->fOutRep << "> Do Calculation" << endl;
-
-        //
-        // get position, where we are
-        //
-        old = ist;
-        ist = fCosy->GetSePos(); // [se]
-
-        //
-        // if the position didn't change continue
-        //
-        /*---
-         if ((int)ist.Zd() == (int)old.Zd() &&
-         (int)ist.Az() == (int)old.Az())
-         continue;
-         */
+        //*fCosy->fOutRep << "> Do Calculation" << endl;
+
+        // Get current position of motors (use last automatically sent
+        // position (PDO) - requesting the position results in problems
+        // with thread safty)
         ZdAz istre = fCosy->GetRePosPdo();
 
-        //
+        // get current position of shaftencoders
+        ZdAz istse = fCosy->GetSePos(); // [se]
+
         // Get time from last shaftencoder position change (position: ist)
-        // FIXME: I cannot take the avarage
-        //
-        // FIXME
-        //time.Zd(fZd1->GetMjd());
-        /* OLD* */
+        // FIXME: Is this correct?
         if (fCosy->fZd1->GetMjd()>fCosy->fZd2->GetMjd())
             time.Zd(fCosy->fZd1->GetMjd());
@@ -475,43 +509,34 @@
             time.Zd(fCosy->fZd2->GetMjd());
 
-        //time.Zd((fZd1->GetMjd()+fZd2->GetMjd())/2.0);
         time.Az(fCosy->fAz->GetMjd());
 
-        //
-        // if Shaftencoder changed position
-        // calculate were we should be
-        //
-        if (phca1 || phca2 /*(int)ist.Zd() != (int)old.Zd()*/)
-        {
-            sollzd = sla.CalcZdAz(fCosy->fRaDec, time.Zd()); // [rad]
-            /*
-            ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
-            sollzd = CorrectTarget(ist, dummy); // [se]
-            */
-            fCosy->fOffset.Zd(fCosy->fOffset.Zd()*(1.-weight)+(ist.Zd()*fCosy->kGearRatio.X()-istre.Zd())*weight);
+        // calculate offset for both axis (only one is needed)
+        const ZdAz offset = (istse*re2se - istre)*weight + fOffset*(weight-1);
+
+        // if Shaftencoder changed position, calculate nominal position
+        if (phca1 || phca2)
+        {
+            const ZdAz dummy = sla.CalcZdAz(fCosy->fRaDec, time.Zd());
+            soll.Zd(dummy.Zd()); // [rad]
+            fOffset.Zd(offset.Zd());
         }
-
-        if (phcaz /*(int)ist.Az() != (int)old.Az()*/)
-        {
-            sollaz = sla.CalcZdAz(fCosy->fRaDec, time.Az()); // [rad]
-            /*
-            ZdAz dummy = fBending(sla.CalcZdAz(fRaDec));
-            sollaz = CorrectTarget(ist, dummy); // [se]
-            */
-            fCosy->fOffset.Az(fCosy->fOffset.Az()*(1.-weight)+(ist.Az()*fCosy->kGearRatio.Y()-istre.Az())*weight);
+        if (phcaz)
+        {
+            const ZdAz dummy = sla.CalcZdAz(fCosy->fRaDec, time.Az());
+            soll.Az(dummy.Az()); // [rad]
+            fOffset.Az(offset.Az());
         }
 
-        ZdAz soll(sollzd.Zd(), sollaz.Az()); // [rad]
-
+        // After calculation of fOffset is done we need 'ist' in rad
+        istse /= fCosy->kResSE/TMath::TwoPi(); // [rad]
+
+        // Calculate the aligned tracking posotion from 'soll'-position
         fCosy->fZdAzSoll = fCosy->AlignTrackingPos(soll);
 
-        ist *= TMath::Pi()*2/16384;
-        soll = fCosy->fBending(fCosy->fZdAzSoll);
-        fCosy->fTrackingError.Set(ist.Zd()-soll.Zd(), ist.Az()-soll.Az());
-
-        //---            fout << setprecision(15) << setw(17) << time.Zd()*60.*60.*24. << " ";
-        //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Zd() << "  ";
-        //---            fout << setprecision(15) << setw(17) << time.Az()*60.*60.*24. << " ";
-        //---            fout << setprecision(5)  << setw(7)  << fTrackingError.Az() << endl;
+        /* --- OLD --- */
+        //fCosy->fTrackingError = istse-fCosy->fBending(fCosy->fZdAzSoll);
+        /* --- NEW --- */
+        fCosy->fTrackingError = fCosy->fBending.CorrectBack(istse)-fCosy->fZdAzSoll;
+        /* --- END --- */
     }
 
Index: trunk/MagicSoft/Cosy/main/MTracking.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MTracking.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/main/MTracking.h	(revision 4076)
@@ -1,4 +1,6 @@
 #ifndef COSY_MTracking
 #define COSY_MTracking
+
+#include "coord.h"
 
 #ifndef COSY_MPointing
@@ -10,4 +12,6 @@
 #endif
 
+class SlaStars;
+
 class MTracking : public MPointing, public MThread
 {
@@ -16,16 +20,23 @@
     Float_t fTrackDec;
 
+    ZdAz    fOffset; // Offset between se and re coordinate system [re]
+
+    MLog *fOut;
+
+    bool RequestRePos();
     bool SetVelocity(const ZdAz &v);
+    bool LimitSpeed(ZdAz *vt, const SlaStars &sla) const;
     bool InitTracking();
-    bool LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const;
+    //void StopTracking();
 
     void *Thread();
 
 public:
-    MTracking(MCosy *cosy, const Log &log) : MPointing(cosy, log), MThread(kFALSE), fTrackAcc(0.1), fTrackDec(0.1) { }
+    MTracking(MCosy *cosy, const Log &log) : MPointing(cosy, log), MThread(kFALSE), fTrackAcc(0.1), fTrackDec(0.1), fOut(0) { }
 
     void TrackPosition(const RaDec &dst); // ra, dec [rad]
     void SetTrackAccDec(Float_t acc, Float_t dec) { fTrackAcc=0.1; fTrackDec=0.1; }
 
+    void SetOut(MLog *fout) { fOut = fout; }
     //void TalkThreadTracking();
   
Index: trunk/MagicSoft/Cosy/starg.cc
===================================================================
--- trunk/MagicSoft/Cosy/starg.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/starg.cc	(revision 4076)
@@ -1,9 +1,7 @@
+#include <iostream.h>
+
 #include <TROOT.h>
 #include <TApplication.h>
 
-#include <iostream.h>
-
-#include "Camera.h"
-#include "PngReader.h"
 #include "MStarguider.h"
 
@@ -18,38 +16,21 @@
     TApplication *app=new TApplication("Starguider", &argc, argv);
 
-    Bool_t dummy = kFALSE;
-
+    Int_t channel = 0;
     for (int i=0; i<argc; i++)
     {
         TString arg(argv[i]);
         if (arg=="-d")
-            dummy = kTRUE;
+            channel = -1;
+        if (arg=="-1")
+            channel = 1;
+        if (arg=="-0")
+            channel = 0;
     }
 
-    PixClient *client=new MStarguider(MObservatory::kMagic1);
-    PixGetter *get;
-
-    if (dummy)
-    {
-        cout << " --> Starting in dummy-mode. <--" << endl;
-        get=new PngReader(*client);
-    }
-    else
-    {
-        cout << " --> Starting in real-mode. <--" << endl;
-        get = new Camera(*client);
-        ((Camera*)get)->Loop(0);
-    }
-
+    PixClient *client=new MStarguider(MObservatory::kMagic1, channel);
     app->Run(kTRUE);
-    get->ExitLoop();
-
-    delete get;
     delete client;
 
-    cout << "Application end...." << endl;
-
-    cout << "Exit." << endl;
-
+    cout << "Application end... Exit." << endl;
     return 0;
 }
Index: trunk/MagicSoft/Cosy/stars.txt
===================================================================
--- trunk/MagicSoft/Cosy/stars.txt	(revision 4075)
+++ trunk/MagicSoft/Cosy/stars.txt	(revision 4076)
@@ -4,4 +4,13 @@
 12 56 11  -05 47 22  3C279 (17.75)
 12 54 02   55 57 35  Alioth (1.77)
+00 08 23   29 05 26  Alpha Andromedae (2.1)
+02 07 10   23 27 45  Alpha Aries (2.00)
+00 40 31   56 32 14  Alpha Cassiopeiae (2.2) 
+21 18 35   62 35 08  Alpha Cephei (2.44)
+15 34 56   26 42 53  Alpha CoronaBorealis (2.23)
+09 27 35  -08 39 31  Alpha Hydrae (2.0)
+17 34 56   12 33 36  Alpha Ophiuchi (2.08)
+03 24 19   49 51 40  Alpha Persei (1.79) 
+11 03 44   61 45 03  Alpha UrsaMajoris (1.79)
 00 08 24   29 05 26  Alpheratz (2.06)
 19 50 47   08 52 06  Altair (0.77)
@@ -9,4 +18,18 @@
 14 15 40   19 10 57  Arcturus (-0.04)
 13 47 33   49 18 48  Benetnasch (1.86)
+01 09 44   35 37 14  Beta Andromedae (2.1)
+01 54 38   20 48 29  Beta Aries (2.6) 
+19 55 19   06 24 24  Beta Aquilae (3.7)
+05 59 32   44 56 51  Beta Aurigae (1.9)
+15 01 57   40 23 26  Beta Bootis (3.5)
+00 09 11   59 08 59  Beta Cassiopeiae (2.3)
+19 30 43   27 57 35  Beta1 Cygni (3.1)
+16 30 13   21 29 23  Beta Herculi (2.77)
+11 49 04   14 34 19  Beta Leonis (2.14)
+15 17 00  -09 22 59  Beta Librae (2.61)
+17 43 28   04 34 02  Beta Ophiuchi (2.77)
+05 26 18   28 36 27  Beta Tauri (1.6)
+14 50 42   74 09 20  Beta UrsaMinoris (2.1)
+05 55 10   07 24 25  Betelgeuse (0.5)
 22 02 43   42 16 40  BL-Lac (14.5)
 05 15 41   45 59 53  Capella (0.08)
@@ -19,7 +42,34 @@
 01 48 19   31 03 18  Dark Patch 4
 20 41 26   45 16 49  Deneb (1.25)
+19 25 30   03 06 53  Delta Aquilae (3.4)
+01 25 49   60 14 07  Delta Cassiopeiae (2.7)
+19 44 59   45 07 51  Delta Cygni (2.87)
 11 03 44   61 45 03  Dubhe (1.79)
+19 05 25   13 51 48  Epsilon Aquilae (2.99)
+14 44 59   27 04 27  Epsilon Bootis (2.7)
+20 46 13   33 58 13  Epsilon Cygni (2.46)
+12 54 02   55 57 35  Epsilon UrsaMajoris (1.77) 
+13 02 11   10 57 33  Epsilon Virginis (2.8)
+19 52 28   01 00 20  Eta Aquilae (3.9)
+13 54 41   18 23 52  Eta Bootis (2.7)
+19 56 19   35 05 00  Eta Cygni (3.89)
+13 47 32   49 18 48  Eta UrsaMajoris (1.86)
+22 57 39  -29 37 20  Formalhaut (1.16)
+02 03 54   42 19 47  Gamma1 Andromedae (2.3)
+19 46 15   10 36 48  Gamma Aquilae (2.7)
+14 32 05   38 18 30  Gamma Bootis (3.0)
+00 56 43   60 43 00  Gamma Cassiopeiae (2.5) 
+20 22 14   40 15 24  Gamma Cygni (2.20)
+17 56 36   51 29 20  Gamma Draconis (2.2)
+06 37 43   16 23 57  Gamma Gemini (1.9)
+00 13 14   15 11 01  Gamma Pegasi (2.8)
+03 04 48   53 30 23  Gamma Persei (2.9)
+11 53 50   53 41 41  Gamma UrsaMajoris (2.4)
+15 20 44   71 50 02  Gamma UrsaMinoris (3.0)
 06 33 54   17 46 48  Geminga
+19 30 42   51 43 47  Iota2 Cygni (3.8)
+19 17 06   53 22 07  Kappa Cygni (3.9)
 18 24 10  -34 23 05  Kaus Australis (1.85)
+19 06 15  -04 52 57  Lambda Aquilae (3.4)
 05 34 32   22 00 52  M1 (8.4)
 13 23 56   54 55 31  Mizar A (2.23)
@@ -27,12 +77,19 @@
 16 53 52   39 45 37  Markarian-501
 02 31 49   89 15 51  Polaris (2.02)
+07 45 19   28 01 34  Pollux (1.1) 
+07 39 18   05 13 30  Procyon (0.4)
 17 34 56   12 33 36  Ras Alhague (2.08)
 17 56 37   51 29 20  Rastaban (2.23)
+10 08 22   11 58 02  Regulus (1.35)
 17 45 12  -28 48 18  Sagittarius-A
 18 55 16  -26 17 48  Sagittarius Sigma-34 (2.02)
 00 40 31   56 32 14  Schedar (2.23)
+06 45 09  -16 42 58  Sirius (-1.5)
 15 02 22  -41 53 48  SN-1006
 13 25 13  -11 09 41  Spica (0.98)
+20 11 18  -00 49 17  Theta Aquilae (3.2)
 17 37 19  -42 59 52  Theta Scorpionis (1.87)
 18 36 56   38 47 01  Vega (0.03)
+19 05 25   13 51 48  Zeta Aquilae (3.0)
+16 41 17   31 36 11  Zeta Herculi (2.81)
 05 37 39   21 08 33  Zeta Tauri (3.0)
Index: trunk/MagicSoft/Cosy/tcpip/MCeCoCom.cc
===================================================================
--- trunk/MagicSoft/Cosy/tcpip/MCeCoCom.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/tcpip/MCeCoCom.cc	(revision 4076)
@@ -2,4 +2,6 @@
 
 #include <iostream>
+
+#include "MString.h"
 
 using namespace std;
@@ -53,15 +55,12 @@
     }
 
-    cout << "Zd/Az: " << zd << "/" << az << "   ";
-    cout << "Ra/Dec: " << ra << "/" << dec << "   ";
-    cout << "Temp: " << temp << "'C   ";
-    cout << "Hum: " << hum << "%   ";
-    cout << "SolRad: " << solar << "W/m²   ";
-    cout << "Wind: " << wind << "km/h" << endl;
-
     fHumidity = hum;
     fTemperature = temp;
     fSolarRadiation = solar;
     fWindSpeed = wind;
+
+    cout << "Zd/Az: " << zd << "/" << az << "  ";
+    cout << "Ra/Dec: " << ra/15 << "h/" << dec << "  ";
+    cout << "SolRad: " << solar << "W/m²" << endl;
 
     fComStat = kCmdReceived;
@@ -86,5 +85,5 @@
 }
 
-bool MCeCoCom::Send(const char *str)
+bool MCeCoCom::Send(const char *cmd, const char *str)
 {
     MTime t;
@@ -100,9 +99,9 @@
     fT.GetTime(h2, m2, s2, ms2);
 
-    const char *msg =
-        Form("%s "
+    MString msg;
+    msg.Print("%s "
              "%02d %04d %02d %02d %02d %02d %02d %03d "
              "%02d %04d %02d %02d %02d %02d %02d %03d "
-             "%s\n", (const char*)fCommand,
+             "%s\n", cmd,
              fStatus,  y1, mon1, d1, h1, m1, s1, ms1,
              fComStat, y2, mon2, d2, h2, m2, s2, ms2,
@@ -113,2 +112,30 @@
     return rc;
 }
+
+TString MCeCoCom::GetWeather() const
+{
+    if (fSolarRadiation<0 || (double)MTime(-1)-(double)fT>11)
+        return "";
+
+    MString str;
+    return str.Print("Temp: %.1f'C  Hum: %.1f%%  Wind: %.1fkm/h",
+                     fTemperature, fHumidity, fWindSpeed);
+}
+
+Int_t MCeCoCom::GetWeatherStatus() const
+{
+    if (fSolarRadiation<0 || (double)MTime(-1)-(double)fT>11)
+        return 0;
+
+    Int_t rc = 0;
+    if (fHumidity>80)
+        rc++;
+    if (fWindSpeed>20)
+        rc++;
+    if (fWindSpeed>30)
+        rc++;
+    if (fWindSpeed>50)
+        rc++;
+
+    return rc;
+}
Index: trunk/MagicSoft/Cosy/tcpip/MCeCoCom.h
===================================================================
--- trunk/MagicSoft/Cosy/tcpip/MCeCoCom.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/tcpip/MCeCoCom.h	(revision 4076)
@@ -24,5 +24,5 @@
     };
 
-    TString fCommand;     // report string of the current system
+    //TString fCommand;     // report string of the current system
     MTime   fT;           // time of last report received
     char    fStatus;      // current status of this system
@@ -43,13 +43,17 @@
 public:
     MCeCoCom::MCeCoCom(const char *cmd, MLog &out=gLog)
-        : MTcpIpIO(out), fCommand(cmd), fStatus(0), fComStat(kNoCmdReceived)
+        : MTcpIpIO(out), /*fCommand(cmd),*/ fStatus(0), fComStat(kNoCmdReceived), fSolarRadiation(-1)
     {
     }
 
-    bool Send(const char *str);
+    bool Send(const char *cmd, const char *str);
     void SetStatus(Byte_t s) { fStatus=s; }
 
     Float_t GetHumidity() const { return fHumidity; }
     Float_t GetTemperature() const { return fTemperature; }
+    Float_t GetWindSpeed() const { return fWindSpeed; }
+
+    TString GetWeather() const;
+    Int_t   GetWeatherStatus() const;
 };
 
Index: trunk/MagicSoft/Cosy/tcpip/MDriveCom.cc
===================================================================
--- trunk/MagicSoft/Cosy/tcpip/MDriveCom.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/tcpip/MDriveCom.cc	(revision 4076)
@@ -6,4 +6,5 @@
 #include "MAstro.h"
 #include "MCosy.h"
+#include "MString.h"
 
 using namespace std;
@@ -53,6 +54,5 @@
     }
 
-    lout << "CC-COMMAND: Track " << ra << "h " << dec << "deg '" << str 
-<< "'" << endl;
+    cout << "CC-COMMAND " << MTime(-1) << " RADEC " << ra << "h " << dec << "d '" << str << "'" << endl;
 
     ra *= 15; // h -> deg
@@ -60,7 +60,7 @@
     RaDec rd[2] = { RaDec(ra, dec), RaDec(ra, dec) };
 
-    cout << "MDriveCom - TRACK... start." << endl;
+    //cout << "MDriveCom - TRACK... start." << endl;
     fQueue->PostMsg(WM_TRACK, &rd, sizeof(rd));
-    cout << "MDriveCom - TRACK... done." << endl;
+    //cout << "MDriveCom - TRACK... done." << endl;
     return true;
 }
@@ -81,11 +81,11 @@
     }
 
-    lout << "CC-COMMAND: Move " << zd << "deg " << az << "deg" << endl;
+    cout << "CC-COMMAND " << MTime(-1) << " ZDAZ " << zd << "deg " << az << "deg" << endl;
 
     ZdAz za(zd, az);
 
-    cout << "MDriveCom - POSITION... start." << endl;
+    //cout << "MDriveCom - POSITION... start." << endl;
     fQueue->PostMsg(WM_POSITION, &za, sizeof(za));
-    cout << "MDriveCom - POSITION... done." << endl;
+    //cout << "MDriveCom - POSITION... done." << endl;
     return true;
 }
@@ -95,7 +95,8 @@
     if (cmd==(TString)"WAIT" && str.IsNull())
     {
-        cout << "MDriveCom - WAIT... start." << endl;
+        //cout << "MDriveCom - WAIT... start." << endl;
+        cout << "CC-COMMAND " << MTime(-1) << " WAIT" << endl;
         fQueue->PostMsg(WM_WAIT);
-        cout << "MDriveCom - WAIT... done." << endl;
+        //cout << "MDriveCom - WAIT... done." << endl;
         return true;
     }
@@ -103,8 +104,8 @@
     if (cmd==(TString)"STOP!" && str.IsNull())
     {
-        cout << "MDriveCom - STOP!... start." << endl;
-        lout << "CC-COMMAND: STOP!" << endl;       
+        //cout << "MDriveCom - STOP!... start." << endl;
+        cout << "CC-COMMAND " << MTime(-1) << " STOP!" << endl;
         fQueue->PostMsg(WM_STOP);
-        cout << "MDriveCom - STOP!... done." << endl;
+        //cout << "MDriveCom - STOP!... done." << endl;
         return true;
     }
@@ -124,9 +125,9 @@
     if (cmd.IsNull() && str.IsNull())
     {
-        cout << "Empty command (single '\\n') received." << endl;
+        cout << "CC-COMMAND " << MTime(-1) << " Empty command (single '\\n') received." << endl;
         return false;
     }
 
-    cout << "Unknown Command: '" << cmd << "':'" << str << "'" << endl;
+    cout << "CC-COMMAND " << MTime(-1) << " Syntax error: '" << cmd << "':'" << str << "'" << endl;
     return false;
 }
@@ -139,5 +140,6 @@
     MAstro::Deg2Dms(deg, sgn, d, m, s);
 
-    str += Form("%c %03d %02d %03d ", sgn, d, m, s);
+    MString txt;
+    str += txt.Print("%c %03d %02d %03d ", sgn, d, m, s);
 }
 
@@ -148,4 +150,5 @@
     // is [deg]
     // er [rad]
+    const MTime t(-1);
 
     rd *= kRad2Deg;
@@ -165,6 +168,5 @@
         SetStatus(4);
 
-    MTime t;
-    t.Now();
+    MString txt;
 
     TString str;
@@ -172,12 +174,17 @@
     Print(str, rd.Dec());   // Dec
     Print(str, 0);          // HA
-    str += Form("%12.6f ", t.GetMjd()); // mjd
+    str += txt.Print("%12.6f ", t.GetMjd()); // mjd
     Print(str, so.Zd());
     Print(str, so.Az());
     Print(str, is.Zd());
     Print(str, is.Az());
-    str += Form("%08.3f ", er.Zd());
-    str += Form("%08.3f", er.Az());
+    str += txt.Print("%08.3f ", er.Zd());
+    str += txt.Print("%08.3f", er.Az());
 
-    return Send(str);
+    return Send("DRIVE-REPORT", str);
 }
+
+bool MDriveCom::SendStatus(const char *stat)
+{
+    return Send("DRIVE-STATUS", stat);
+}
Index: trunk/MagicSoft/Cosy/tcpip/MDriveCom.h
===================================================================
--- trunk/MagicSoft/Cosy/tcpip/MDriveCom.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/tcpip/MDriveCom.h	(revision 4076)
@@ -37,4 +37,5 @@
 
     bool SendReport(UInt_t stat, RaDec rd, ZdAz so, ZdAz is, ZdAz er);
+    bool SendStatus(const char *stat);
 };
 
Index: trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.cc
===================================================================
--- trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.cc	(revision 4076)
@@ -33,5 +33,6 @@
      */
 
-MTcpIpIO::MTcpIpIO(MLog &out) : MThread(false), Log(out), fRxSocket(NULL), fServSock(NULL)
+MTcpIpIO::MTcpIpIO(MLog &out)
+    : MThread(false), Log(out), fRxSocket(NULL), fServSock(NULL), fSendInterval(1000)
 {
     fTxSocket = new TSocket("ceco", 7304);
@@ -49,18 +50,18 @@
     // Now delete all TCP/IP objects
     //
-    cout << "Delete TxSocket " << fTxSocket << "..." << flush;
+    //cout << "Delete TxSocket " << fTxSocket << "..." << flush;
     delete fTxSocket;
-    cout << "Done." << endl;
+    //cout << "Done." << endl;
     if (fServSock)
     {
-        cout << "Delete ServSock " << fServSock << "..." << flush;
+        //cout << "Delete ServSock " << fServSock << "..." << flush;
         delete fServSock;
-        cout << "Done." << endl;
+        //cout << "Done." << endl;
     }
     if (fRxSocket)
     {
-        cout << "Delete RxSocket " << fRxSocket << "..." << flush;
+        //cout << "Delete RxSocket " << fRxSocket << "..." << flush;
         delete fRxSocket;
-        cout << "Done." << endl;
+        //cout << "Done." << endl;
     }
 }
@@ -68,4 +69,19 @@
 bool MTcpIpIO::Send(const char *msg)
 {
+    const MTime t(-1);
+
+    if ((double)t-(double)fTime<0.001*fSendInterval)
+        return true;
+
+    const Int_t rc = lout.IsOutputDeviceEnabled(MLog::eGui);
+    lout.DisableOutputDevice(MLog::eGui);
+    lout.Lock();
+    lout << msg << flush;
+    lout.UnLock();
+    if (rc)
+        lout.EnableOutputDevice(MLog::eGui);
+
+    fTime = t;
+
     if (!fTxSocket->IsValid())
         return false;
@@ -112,5 +128,5 @@
             switch (fServSock->GetErrorCode())
             {
-            case 0: cout << "No error." << endl; break;
+            case  0: cout << "No error." << endl; break;
             case -1: cout << "low level socket() call failed." << endl; break;
             case -2: cout << "low level bind() call failed." << endl; break;
Index: trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.h
===================================================================
--- trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/tcpip/MTcpIpIO.h	(revision 4076)
@@ -7,4 +7,7 @@
 #ifndef COSY_Log
 #include "log.h"
+#endif
+#ifndef MARS_MTime
+#include "MTime.h"
 #endif
 
@@ -19,4 +22,7 @@
     TSocket       *fRxSocket;
     TServerSocket *fServSock;
+
+    MTime fTime;
+    Int_t fSendInterval; // [ms]
 
     void Clear();
Index: trunk/MagicSoft/Cosy/videodev/Camera.cc
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/videodev/Camera.cc	(revision 4076)
@@ -17,20 +17,32 @@
 inline int Camera::Ioctl(int req, void *opt, const char *str)
 {
-    int rc = ioctl(fd, req, opt);
-
-    if (rc==-1)
-    {
-        cout << "Error! Ioctl " << req << ": ";
+    while (1)
+    {
+        const int rc = ioctl(fd, req, opt);
+        if (rc>=0)
+            return rc;
+
+        // errno== 4: Interrupted system call
+        // errno==16: Device or resource busy
+        if (errno==4 || errno==16)
+        {
+            cout << "Camera: ioctl returned rc=" << rc << " '";
+            cout << (str?str:strerror(errno)) << "' (errno = " << errno << ")" << endl;
+            usleep(10);
+            continue;
+        }
+
+        cout << "Error! Ioctl " << hex << req << ": errno=" << dec << errno << " - ";
         cout << (str?str:strerror(errno)) << " (rc=" << rc << ")" << endl;
-    }
-
-    return rc;
+        return rc;
+    }
+    return -1;
 }
 
 void Camera::Error(const char *str, int fatal)
 {
-    cout << endl
-        << (fatal?"Fatal ":"") << "Error! " << str << ": " << strerror(errno)
-        << endl;
+    cout << endl;
+    cout << (fatal?"Fatal ":"") << "Error! " << str << ": " << strerror(errno);
+    cout << endl;
 
     if (fatal)
@@ -39,15 +51,16 @@
 void Camera::SigInit()
 {
-    return;
-    struct sigaction act, old;
-
-    memset(&act, 0, sizeof(act));
-
-    act.sa_handler = SigAlarm;
-
-    sigemptyset(&act. sa_mask);
-    sigaction(SIGALRM, &act, &old);
-
-    // signal(SIGINT, ctrlc);
+    /*
+     struct sigaction act, old;
+
+     memset(&act, 0, sizeof(act));
+
+     act.sa_handler = SigAlarm;
+
+     sigemptyset(&act. sa_mask);
+     sigaction(SIGALRM, &act, &old);
+
+     // signal(SIGINT, ctrlc);
+     */
 }
 
@@ -74,9 +87,13 @@
 int Camera::StartGrab(unsigned int frame)
 {
+    // We could also get RGB555, RGB565 and RGB32. But we want
+    // RGB24 because we have a 8bit DAC which gives us 8bit per
+    // color ==> RGB24 which is in the following the most simple
+    // to process.
     static struct video_mmap gb =
     {
-        0,                     // frame
-        rows, cols,            // height, width
-        VIDEO_PALETTE_RGB24    // palette
+        0,                  // frame
+        rows, cols,         // height, width
+        VIDEO_PALETTE_RGB24 // palette
     };
 
@@ -95,15 +112,7 @@
 }
 
-Camera::Camera(PixClient &client) : fd(-1), iBufferSize(0), fClient(client), fMutex(), fCond(&fMutex)
-{
-    cout << "Starting thread..." << flush;
-    //pthread_cond_init(&fCond, NULL);
-    //pthread_mutex_init(&fMux, NULL);
-    //pthread_mutex_lock(&fMux);
-    fMutex.Lock();
-    pthread_create(&fThread, NULL, MapThread, this);
-    cout << "done." << endl;
-
-    cout << "/dev/video: opening..." << flush;
+Camera::Camera(PixClient &client, Int_t nch) : fd(-1), iBufferSize(0), fClient(client), fCond(), fMutex(fCond.GetMutex())
+{
+    cout << "Camera: " << this << " /dev/video: opening..." << flush;
 
     //
@@ -126,6 +135,7 @@
     // get input channel 0 information
     //
+
     struct video_channel ch;
-    ch.channel = 0;
+    ch.channel = nch;
     Ioctl(VIDIOCGCHAN, &ch);
 
@@ -160,29 +170,35 @@
     cout << "Buffer Size: " << (void*)iBufferSize << endl;
     cout << "grab: use: 768x576 24 bit TrueColor (LE: bgr) = " << (void*)(768*576*3) << "b" << endl;
+
+//    if (fMutex->UnLock()==13)
+//        cout << "Camera::Camera - tried to unlock mutex locked by other thread." << endl;
+
+    cout << "Starting thread..." << flush;
+    //pthread_cond_init(&fCond, NULL);
+    //pthread_mutex_init(&fMux, NULL);
+    //pthread_mutex_lock(&fMux);
+//    if (fMutex->Lock()==13)
+//        cout << "Camera::Camera - mutex is already locked by this thread" << endl;
+    pthread_create(&fThread, NULL, MapThread, this);
+    cout << "done." << endl;
+
 }
 
 Camera::~Camera()
 {
-    cout << "Stopping thread..." << flush;
     pthread_cancel(fThread);
-    //pthread_mutex_destroy(&fMux);
-    //pthread_cond_destroy(&fCond);
+
+    cout << "/dev/video: closing... " << flush;
+    if (fd != -1)
+    {
+        close(fd);
+        fd = -1;
+    }
     cout << "done." << endl;
-
-    cout << "/dev/video: closing... " << flush;
 
     // unmap device memory
     if ((int)pMapBuffer != -1)
         munmap(pMapBuffer, iBufferSize);
-
-    if (fd != -1)
-    {
-        close(fd);
-        fd = -1;
-    }
-
-    cout << " Done." << endl;
-}
-
+}
 
 void *Camera::MapThread(void *arg)
@@ -198,4 +214,29 @@
 }
 
+void Camera::ExitLoop()
+{
+    //    cout << "ExitLoop..." << endl;
+    fStop = 1;
+    while (IsRunning())
+        usleep(1);
+    //    cout << "Loop exited." << endl;
+}
+
+//
+// flag if the execution is running or not
+//
+int Camera::IsRunning() const
+{
+    const Int_t rc = fMutex->TryLock();
+    if (rc==0)
+        return false;
+
+    if (rc==13)
+        return false;
+
+    fMutex->UnLock();
+    return true;
+}
+
 void Camera::LoopStep(const unsigned long n)
 {
@@ -217,8 +258,12 @@
 {
 #define IsOdd(i) (2*(i/2)!=i)
+    cout << "Camera::Thread started..." << endl;
     while (1)
     {
-        //pthread_cond_wait(&fCond, &fMux);
+        //cout << "Wait..." << flush;
         fCond.Wait();
+        //cout << "done." << endl;
+        if (fd==-1)
+            break;
 
         MStopwatch t;
@@ -259,7 +304,9 @@
         t.Stop();
         t.Print(i);
-
-        fRunning = 0;
-    }
+    }
+
+    fMutex->UnLock();
+
+    cout << "Camera::Thread.. stopped." << endl;
 }
 
@@ -272,20 +319,9 @@
     }
 
-    //
-    // Stop running loop
-    //
-    fStop = 1;
-
-    //
-    // Wait until loop is stopped (pthread_cond_wait is executing)
-    // set new number of frames to process
-    //
-    fMutex.Lock();
-    //pthread_mutex_lock(&fMux);
-    fNum     = nof;
-    fStop    = 0;
-    fRunning = 1;
-    fMutex.UnLock();
-    //pthread_mutex_unlock(&fMux);
+    cout << "Loop..." << endl;
+    ExitLoop();
+
+    fNum  = nof;
+    fStop = 0;
 
     //
@@ -293,5 +329,4 @@
     //
     fCond.Broadcast();
-    //pthread_cond_signal(&fCond);
 }
 
Index: trunk/MagicSoft/Cosy/videodev/Camera.h
===================================================================
--- trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/videodev/Camera.h	(revision 4076)
@@ -45,5 +45,5 @@
 
     int fStop;
-    int fRunning;
+//    int fRunning;
 
     char fImg[cols*rows];
@@ -53,6 +53,6 @@
 
     pthread_t  fThread;
-    TMutex     fMutex;
     TCondition fCond;
+    TMutex    *fMutex;
     //pthread_mutex_t fMux;
     //pthread_cond_t  fCond;
@@ -81,5 +81,5 @@
 
 public:
-    Camera(PixClient &client);
+    Camera(PixClient &client, Int_t ch=0);
     virtual ~Camera();
 
@@ -88,15 +88,6 @@
     //
     void Loop(const unsigned long nof=0);
-    void ExitLoop()
-    {
-        fStop = 1;
-        while (IsRunning())
-            usleep(1);
-    }
-
-    //
-    // flag if the execution is running or not
-    //
-    int IsRunning() const { return fRunning; }
+    void ExitLoop();
+    int  IsRunning() const;
 
     //
Index: trunk/MagicSoft/Cosy/videodev/FilterLed.cc
===================================================================
--- trunk/MagicSoft/Cosy/videodev/FilterLed.cc	(revision 4075)
+++ trunk/MagicSoft/Cosy/videodev/FilterLed.cc	(revision 4076)
@@ -15,5 +15,5 @@
         return;
 
-    for (int dx=-(int)(rpix*0.7); dx<(int)(rpix*0.7); dx++)
+    for (int dx=-(int)(rpix*0.7); dx<(int)(rpix*0.7); dx+=2)
     {
         const int dy = (int)sqrt(rpix*rpix-dx*dx);
@@ -64,5 +64,4 @@
     DrawBox(x+5, y, x+8, y, m);
     DrawBox(x, y-8, x, y-5, m);
-    return;
 }
 
@@ -76,5 +75,5 @@
 
     //
-    // calculate mean value
+    // calculate mean value (speed optimized)
     //
     while (s<e0)
@@ -104,10 +103,10 @@
 
 int FilterLed::GetMeanPosition(const int x, const int y,
-                               const int box, float &mx, float &my) const
+                               const int box, float &mx, float &my, unsigned int &sum) const
 {
     unsigned int sumx=0;
     unsigned int sumy=0;
-    unsigned int sum =0;
-
+
+    sum=0;
     for (int dx=x-box; dx<x+box+1; dx++)
         for (int dy=y-box; dy<y+box+1; dy++)
@@ -129,5 +128,6 @@
 {
     float mx, my;
-    return GetMeanPosition(x, y, box, mx, my);
+    unsigned int sum;
+    return GetMeanPosition(x, y, box, mx, my, sum);
 }
 /*
@@ -252,8 +252,8 @@
 void FilterLed::Execute(Leds &leds, int xc, int yc) const
 {
-    int x0 = xc-fBoxW;
-    int x1 = xc+fBoxW;
-    int y0 = yc-fBoxH;
-    int y1 = yc+fBoxH;
+    int x0 = xc-fBox;
+    int x1 = xc+fBox;
+    int y0 = yc-fBox;
+    int y1 = yc+fBox;
 
     if (x0<0) x0=0;
@@ -280,4 +280,5 @@
     sq  /= wx*hy;
 
+    // 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);
@@ -348,5 +349,6 @@
 
         Float_t mx, my;
-        GetMeanPosition(pos[i]%fW, pos[i]/fW, 5, mx, my);
+        unsigned int sum;
+        GetMeanPosition(pos[i]%fW, pos[i]/fW, 5, mx, my, sum);
 
         leds.Add(mx, my, 0, 0, mag[i]);
@@ -354,4 +356,119 @@
 
     RemoveTwinsInterpol(leds, first, 5);
+}
+
+void FilterLed::FindStar(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 nuymber 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+1; x++)
+        for (int y=ya; y<yb+1; 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+1; x+=2)
+    {
+        fImg[ya*fW+x]=0xf0;
+        fImg[yb*fW+x]=0xf0;
+    }
+    for (int y=ya; y<yb+1; 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);
+
+    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);
 }
 
Index: trunk/MagicSoft/Cosy/videodev/FilterLed.h
===================================================================
--- trunk/MagicSoft/Cosy/videodev/FilterLed.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/videodev/FilterLed.h	(revision 4076)
@@ -17,11 +17,10 @@
     int fW;
     int fH;
-    int fBoxW;
-    int fBoxH;
+    int fBox;
     float fCut;
 
     void GetMinMax(const int offset, byte *min, byte *max) const;
     int  GetMeanPosition(const int x, const int y, const int box) const;
-    int  GetMeanPosition(const int x, const int y, const int box, float &mx, float &my) const;
+    int  GetMeanPosition(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,
@@ -31,17 +30,17 @@
 public:
     FilterLed(byte *img, int w, int h, double cut=2.5)
-        : fImg(img), fW(w), fH(h), fBoxW(w/2), fBoxH(h/2), fCut(cut)
+        : fImg(img), fW(w), fH(h), fBox(w>h?w:h), fCut(cut)
     {
     }
 
     FilterLed(byte *img, int w, int h, int box, double cut=2.5)
-        : fImg(img), fW(w), fH(h), fBoxW(box), fBoxH(box), fCut(cut)
+        : fImg(img), fW(w), fH(h), fBox(box), fCut(cut)
     {
     }
 
-    FilterLed(byte *img, int w, int h, int boxw, int boxh, double cut=2.5)
-        : fImg(img), fW(w), fH(h), fBoxW(boxw), fBoxH(boxh), fCut(cut)
-    {
-    }
+    void SetBox(int box)   { fBox = box; }
+    void SetCut(float cut) { fCut = cut; }
+
+    void FindStar(Leds &leds, int xc, int yc) const;
 
     void Execute(Leds &leds, int xc, int yc) const;
@@ -55,5 +54,5 @@
     void Stretch() const;
     void DrawCircle(float cx, float cy, float r, byte col=0x40) const;
-    void DrawCircle(float r, byte col=0x40) const { DrawCircle(r, fW/2.+.5, fH/2.+.5, col); }
+    void DrawCircle(float r, byte col=0x40) const { DrawCircle(fW/2, fH/2, r, col); }
     void DrawCircle(const Ring &c, byte col=0x40) const;
     void DrawCircle(const Ring &c, double r, byte col) const;
Index: trunk/MagicSoft/Cosy/videodev/PixGetter.h
===================================================================
--- trunk/MagicSoft/Cosy/videodev/PixGetter.h	(revision 4075)
+++ trunk/MagicSoft/Cosy/videodev/PixGetter.h	(revision 4076)
@@ -5,4 +5,5 @@
 {
 public:
+    virtual ~PixGetter() { }
     virtual void ExitLoop() {}
 };
