Index: trunk/MagicSoft/Cosy/Changelog
===================================================================
--- trunk/MagicSoft/Cosy/Changelog	(revision 923)
+++ trunk/MagicSoft/Cosy/Changelog	(revision 924)
@@ -1,3 +1,24 @@
                                                                   -*-*- END -*-*-
+ 2001/09/06 - Thomas Bretz:
+
+   * MCosy.[cc,h]
+     - moved to main
+     - moved logging files to log dir
+     
+   * MStarguider.[h,cc]
+     - moved to main
+   
+   * Starguider.[h,cc]:
+     - renamed to MGStarguider.[h,cc]
+     - moved to gui dir
+     
+   * cosy.cc:
+     - moved logging file to log dir
+     
+   * starg.cc:
+     - removed InitGui stuff
+
+
+
  2001/08/30 - Thomas Bretz:
  
Index: trunk/MagicSoft/Cosy/Makefile
===================================================================
--- trunk/MagicSoft/Cosy/Makefile	(revision 923)
+++ trunk/MagicSoft/Cosy/Makefile	(revision 924)
@@ -23,5 +23,5 @@
 SOLIB    = 
 CINT     = M
-INCLUDES = -I. -Iincl -Ibase -Igui -Idevdrv -Icandrv -Ivideodev -Icatalog
+INCLUDES = -I. -Imain  -Ibase -Icandrv -Iincl -Igui -Ivideodev -Icatalog
 LIBS     = -lpng -lz -L/usr/X11R6/lib -lpthread
 
@@ -38,4 +38,5 @@
 #
 SUBDIRS = \
+        main     \
         gui      \
         candrv   \
@@ -52,5 +53,5 @@
 .SUFFIXES: .c .cc .h .o 
 
-SRCFILES = MCosy.cc Starguider.cc
+SRCFILES =
 
 SRCS    = $(SRCFILES)
@@ -112,4 +113,7 @@
 	@cd catalog; make mrproper; cd ..
 	@echo "cd .."
+	@echo "cd main"
+	@cd main; make mrproper; cd ..
+	@echo "cd .."
 
 tar:	mrproper
Index: trunk/MagicSoft/Cosy/cosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/cosy.cc	(revision 923)
+++ trunk/MagicSoft/Cosy/cosy.cc	(revision 924)
@@ -1,4 +1,2 @@
-#include "MCosy.h"
-
 #include <iomanip.h>
 #include <fstream.h>
@@ -9,4 +7,5 @@
 #include <TApplication.h>
 
+#include "MCosy.h"
 #include "MLogManip.h"
 #include "base/timer.h"
@@ -23,5 +22,5 @@
     // this must move to MGCosy !!!! (or MApplication)
     //
-    MLog lout("cosy.log", kTRUE);
+    MLog lout("log/cosy.log", kTRUE);
 
     clog("Starting Cosy at " << time.GetTimeStr() << " ...");
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 923)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 924)
@@ -59,5 +59,5 @@
     void DisplayVal();
 
-    bool IsPosHasChanged() const { return fPosHasChanged; }
+    bool PosHasChanged() const { return fPosHasChanged; }
     void ResetPosHasChanged() { fPosHasChanged = false; }
 };
Index: trunk/MagicSoft/Cosy/gui/MGStarguider.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGStarguider.cc	(revision 924)
+++ trunk/MagicSoft/Cosy/gui/MGStarguider.cc	(revision 924)
@@ -0,0 +1,345 @@
+#include "MGStarguider.h"
+
+#include <iostream.h> // cout
+
+#include <TGMenu.h>
+#include <TSystem.h>
+#include <TGSplitter.h>    // TGHorizontal3DLine
+
+#include "MGImage.h"
+#include "MGCoordinates.h"
+
+#include "Filter.h"
+#include "Writer.h"
+#include "base/timer.h"
+
+enum {
+    IDM_kFilter,
+    IDM_kCatalog,
+    IDM_kStart,
+    IDM_kStop,
+    IDM_kFileType,
+    IDM_kPPM,
+    IDM_kPNG,
+    IDM_kOnce,
+    IDM_kContinous,
+    IDM_kRate25ps,
+    IDM_kRate5ps,
+    IDM_kRate1s,
+    IDM_kRate5s,
+    IDM_kRate30s,
+    IDM_kRate1m,
+    IDM_kRate5m,
+    IDM_kSetup,
+    IDM_kLimMag3,
+    IDM_kLimMag4,
+    IDM_kLimMag5,
+    IDM_kLimMag6,
+    IDM_kLimMag7,
+    IDM_kLimMag8,
+    IDM_kLimMag9
+};
+
+MGStarguider::MGStarguider()
+: Camera(), TGMainFrame(gClient->GetRoot(), 768, 700), fRaDec(180, 40)
+{
+    // p = pointer to MainFrame (not owner)
+
+    const TGWindow *p=gClient->GetRoot();
+
+    //
+    // Create Menu for MGStarguider Display
+    //
+    fDisplay = new TGPopupMenu(p);
+    fDisplay->AddEntry("&Filter",      IDM_kFilter);
+    fDisplay->AddEntry("Sao &Catalog", IDM_kCatalog);
+    fDisplay->Associate(this);
+    fList.Add(fDisplay);
+
+    fFileType = new TGPopupMenu(p);
+    fFileType->AddEntry("PP&M", IDM_kPPM);
+    fFileType->AddEntry("&PNG", IDM_kPNG);
+    fFileType->CheckEntry(IDM_kPNG);
+    fFileType->Associate(this);
+    fList.Add(fFileType);
+
+    fWriteType = new TGPopupMenu(p);
+    fWriteType->AddEntry("Once",      IDM_kOnce);
+    fWriteType->AddEntry("Continous", IDM_kContinous);
+    fWriteType->CheckEntry(IDM_kOnce);
+    fWriteType->Associate(this);
+    fList.Add(fWriteType);
+
+    fWriteRate = new TGPopupMenu(p);
+    fWriteRate->AddEntry("25/s", IDM_kRate25ps);
+    fWriteRate->AddEntry("5/s",  IDM_kRate5ps);
+    fWriteRate->AddEntry("1s",   IDM_kRate1s);
+    fWriteRate->AddEntry("5s",   IDM_kRate5s);
+    fWriteRate->AddEntry("30s",  IDM_kRate30s);
+    fWriteRate->AddEntry("1min", IDM_kRate1m);
+    fWriteRate->AddEntry("5min", IDM_kRate5m);
+    fWriteRate->CheckEntry(IDM_kRate1m);
+    fWriteRate->Associate(this);
+    fList.Add(fWriteRate);
+
+    fWrtRate = 25*60;
+
+    fWrite = new TGPopupMenu(p);
+    fWrite->AddEntry("&Start",      IDM_kStart);
+    fWrite->AddEntry("Sto&p",       IDM_kStop);
+    fWrite->AddSeparator();
+    fWrite->AddPopup("File &Type",  fFileType);
+    fWrite->AddPopup("&Write Type", fWriteType);
+    fWrite->AddPopup("Write &Rate", fWriteRate);
+    fWrite->DisableEntry(IDM_kStop);
+    fWrite->Associate(this);
+    fList.Add(fWrite);
+
+    fLimMag = new TGPopupMenu(p);
+    fLimMag->AddEntry("3", IDM_kLimMag3);
+    fLimMag->AddEntry("4", IDM_kLimMag4);
+    fLimMag->AddEntry("5", IDM_kLimMag5);
+    fLimMag->AddEntry("6", IDM_kLimMag6);
+    fLimMag->AddEntry("7", IDM_kLimMag7);
+    fLimMag->AddEntry("8", IDM_kLimMag8);
+    fLimMag->AddEntry("9", IDM_kLimMag9);
+    fLimMag->CheckEntry(IDM_kLimMag8);
+    fLimMag->Associate(this);
+    fList.Add(fLimMag);
+
+    fSao.SetLimitMag(8.0);
+
+    fSetup = new TGPopupMenu(p);
+    fSetup->AddPopup("Lim. &Magnitude", fLimMag);
+    fSetup->Associate(this);
+    fList.Add(fSetup);
+
+    fMenu = new TGMenuBar(this, 0, 0, kHorizontalFrame);
+    fMenu->AddPopup("&Display", fDisplay, NULL);
+    fMenu->AddPopup("&Write",   fWrite,   NULL);
+    fMenu->AddPopup("&Setup",   fSetup,   NULL);
+    fMenu->Resize(fMenu->GetDefaultSize());
+    AddFrame(fMenu); //, new TGLayoutHints (kLHintsNormal, 0, 4, 0, 0));
+    fList.Add(fMenu);
+
+    fCRaDec = new MGCoordinates(this, kETypeRaDec);
+    fCRaDec->Move(1, fMenu->GetDefaultHeight()+584);
+    AddFrame(fCRaDec);
+    fList.Add(fCRaDec);
+
+    fCZdAz = new MGCoordinates(this, kETypeZdAz);
+    fCZdAz->Move(240+12, fMenu->GetDefaultHeight()+584);
+    AddFrame(fCZdAz);
+    fList.Add(fCZdAz);
+
+    // TGHorizontal3DLine *fLineSep = new TGHorizontal3DLine(this);
+    // AddFrame(fLineSep, new TGLayoutHints (kLHintsNormal | kLHintsExpandX));
+    // fList.Add(fLineSep);
+
+    //
+    // Create Image Display
+    //
+    fImage = new MGImage(this, 768, 576);
+    fImage->Move(0, fMenu->GetDefaultHeight());
+    AddFrame(fImage);
+    fList.Add(fImage);
+
+    //
+    // Make everything visible
+    //
+    SetWindowName("MGStarguider Main Window");
+    SetIconName("MGStarguider");
+
+    MapSubwindows();
+    MapWindow();
+
+    fSao.SetPixSize(0.006);
+}
+
+MGStarguider::~MGStarguider()
+{
+    cout << "Camera Display destroyed." << endl;
+}
+
+void MGStarguider::Layout()
+{
+    // Resize(GetDefaultSize());
+}
+
+void MGStarguider::CloseWindow()
+{
+    cout << "EventDisplay::CloseWindow: Exit Application Loop." << endl;
+
+    ExitLoop();
+
+    gSystem->ExitLoop();
+}
+
+Bool_t MGStarguider::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
+{
+    switch (GET_MSG(msg))
+    {
+    case kC_COMMAND:
+        switch (GET_SUBMSG(msg))
+        {
+        case kCM_MENU:
+            switch (mp1)
+            {
+            case IDM_kCatalog:
+                if (fDisplay->IsEntryChecked(IDM_kCatalog))
+                    fDisplay->UnCheckEntry(IDM_kCatalog);
+                else
+                    fDisplay->CheckEntry(IDM_kCatalog);
+                return kTRUE;
+
+            case IDM_kFilter:
+                if (fDisplay->IsEntryChecked(IDM_kFilter))
+                    fDisplay->UnCheckEntry(IDM_kFilter);
+                else
+                    fDisplay->CheckEntry(IDM_kFilter);
+                return kTRUE;
+
+            case IDM_kStart:
+                fWrite->DisableEntry(IDM_kStart);
+                fWrite->EnableEntry(IDM_kStop);
+                return kTRUE;
+
+            case IDM_kStop:
+                fWrite->DisableEntry(IDM_kStop);
+                fWrite->EnableEntry(IDM_kStart);
+                return kTRUE;
+
+            case IDM_kPNG:
+                fFileType->CheckEntry(IDM_kPNG);
+                fFileType->UnCheckEntry(IDM_kPPM);
+                return kTRUE;
+
+            case IDM_kPPM:
+                fFileType->CheckEntry(IDM_kPPM);
+                fFileType->UnCheckEntry(IDM_kPNG);
+                return kTRUE;
+
+            case IDM_kOnce:
+                fWriteType->CheckEntry(IDM_kOnce);
+                fWriteType->UnCheckEntry(IDM_kContinous);
+                return kTRUE;
+
+            case IDM_kContinous:
+                fWriteType->CheckEntry(IDM_kContinous);
+                fWriteType->UnCheckEntry(IDM_kOnce);
+                return kTRUE;
+
+            case IDM_kRate25ps:
+            case IDM_kRate5ps:
+            case IDM_kRate1s:
+            case IDM_kRate5s:
+            case IDM_kRate30s:
+            case IDM_kRate1m:
+            case IDM_kRate5m:
+                for (int i=IDM_kRate25ps; i<=IDM_kRate5m; i++)
+                    if (mp1==i)
+                        fWriteRate->CheckEntry(i);
+                    else
+                        fWriteRate->UnCheckEntry(i);
+                switch (mp1)
+                {
+                case IDM_kRate25ps:
+                    fWrtRate = 1;
+                    return kTRUE;
+                case IDM_kRate5ps:
+                    fWrtRate = 5;
+                    return kTRUE;
+                case IDM_kRate1s:
+                    fWrtRate = 25;
+                    return kTRUE;
+                case IDM_kRate5s:
+                    fWrtRate = 5*25;
+                    return kTRUE;
+                case IDM_kRate30s:
+                    fWrtRate = 30*25;
+                    return kTRUE;
+                case IDM_kRate1m:
+                    fWrtRate = 60*25;
+                    return kTRUE;
+                case IDM_kRate5m:
+                    fWrtRate = 5*60*25;
+                    return kTRUE;
+                }
+                return kTRUE;
+
+            case IDM_kLimMag3:
+            case IDM_kLimMag4:
+            case IDM_kLimMag5:
+            case IDM_kLimMag6:
+            case IDM_kLimMag7:
+            case IDM_kLimMag8:
+            case IDM_kLimMag9:
+                for (int i=IDM_kLimMag3; i<=IDM_kLimMag9; i++)
+                    if (mp1==i)
+                        fLimMag->CheckEntry(i);
+                    else
+                        fLimMag->UnCheckEntry(i);
+
+                fSao.SetLimitMag(mp1-IDM_kLimMag3+3);
+                return kTRUE;
+            }
+            break;
+        }
+        break;
+    }
+    return kTRUE;
+}
+
+void MGStarguider::ProcessFrame(const unsigned long n, byte *img, struct timeval *tm)
+{
+
+    if (!fWrite->IsEntryEnabled(IDM_kStart) &&
+        (!(n%fWrtRate) || fWriteType->IsEntryChecked(IDM_kOnce)))
+    {
+        if (fFileType->IsEntryChecked(IDM_kPNG))
+        {
+            static int num = 0;
+
+            char name[80];
+            sprintf(name, "pix/file%04d.png", num);
+            Writer::Png(name, img, tm);
+        }
+
+        if (fFileType->IsEntryChecked(IDM_kPPM))
+        {
+            static int num = 0;
+            char name[80];
+            sprintf(name, "pix/file%04d.ppm", num);
+            Writer::Ppm(name, img);
+        }
+
+        if (fWriteType->IsEntryChecked(IDM_kOnce))
+            ProcessMessage(MK_MSG(kC_COMMAND, kCM_MENU), IDM_kStop, 0);
+    }
+
+    if (!(n%25))
+    {
+        cout << "Img: " << n << endl;
+
+        if (fDisplay->IsEntryChecked(IDM_kFilter))
+            Filter::Execute(img);
+
+        if (fDisplay->IsEntryChecked(IDM_kCatalog))
+        {
+            byte cimg[768*576];
+
+            XY xy = fCRaDec->GetCoordinates();
+
+            fRaDec.Set(xy.X(), xy.Y());
+
+            Timer time(tm);
+            fSao.GetImg(img, cimg, time.CalcMjd(), fRaDec);
+            fImage->DrawColImg(img, cimg);
+
+            fCZdAz->SetCoordinates(fSao.GetZdAz());
+        }
+        else
+            fImage->DrawImg(img);
+    }
+
+}
Index: trunk/MagicSoft/Cosy/gui/MGStarguider.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGStarguider.h	(revision 924)
+++ trunk/MagicSoft/Cosy/gui/MGStarguider.h	(revision 924)
@@ -0,0 +1,65 @@
+#ifndef MGSTARGUIDER_H
+#define MGSTARGUIDER_H
+
+#ifndef ROOT_TGFrame
+#include <TGFrame.h>
+#endif
+#ifndef CAMERA_H
+#include "Camera.h"
+#endif
+
+#include "MGList.h"
+#include "MGImage.h"
+#include "StarCatalog.h"
+
+class TGMenuBar;
+class TGPopupMenu;
+
+class MGImage;
+class MGCoordinates;
+
+class MGStarguider : public Camera, public TGMainFrame
+{
+private:
+    MGList         fList;
+
+    TGMenuBar     *fMenu;
+    MGImage       *fImage;
+
+    TGPopupMenu   *fDisplay;
+    TGPopupMenu   *fWrite;
+    TGPopupMenu   *fFileType;
+    TGPopupMenu   *fWriteType;
+    TGPopupMenu   *fWriteRate;
+    TGPopupMenu   *fSetup;
+    TGPopupMenu   *fLimMag;
+
+    MGCoordinates *fCRaDec;
+    MGCoordinates *fCZdAz;
+
+    StarCatalog    fSao;
+
+    RaDec fRaDec;
+
+    int fWrtRate;
+
+    void SetPixSize(const double pixsize);
+
+public:
+    MGStarguider();
+    virtual ~MGStarguider();
+
+    void Update();
+
+    void Layout();
+    void CloseWindow();
+
+    Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2);
+
+    //
+    // Execution of one frame - this function may be overloaded!
+    //
+    void ProcessFrame(const unsigned long n, byte *img, struct timeval *tm);
+};
+
+#endif
Index: trunk/MagicSoft/Cosy/gui/Makefile
===================================================================
--- trunk/MagicSoft/Cosy/gui/Makefile	(revision 923)
+++ trunk/MagicSoft/Cosy/gui/Makefile	(revision 924)
@@ -20,5 +20,6 @@
 # @endcode 
 
-INCLUDES = -I. -I.. -I../base -I../slalib -I../candrv -I../incl -I../catalog
+INCLUDES = -I. -I.. -I../base -I../slalib -I../candrv -I../incl \
+	   -I../catalog -I../videodev
 
 # @code 
@@ -38,4 +39,5 @@
 	   MGAccuracy.cc \
 	   MGVelocity.cc \
+           MGStarguider.cc \
 	   MGSkyPosition.cc
 
Index: trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 924)
@@ -0,0 +1,942 @@
+#include "MCosy.h"
+
+#include <iomanip.h>
+#include <fstream.h>
+#include <iostream.h>
+
+#include <TROOT.h>
+#include <TEnv.h>
+#include <TSystem.h>
+#include <TApplication.h>
+#include <TTimer.h>
+
+#include "MGCosy.h"
+#include "SlaStars.h"
+
+#include "slalib/slalib.h"  // FIXME: REMOVE
+
+#include "macs.h"
+#include "base/timer.h"
+#include "shaftencoder.h"
+
+//#include <sys/resource.h>  // PRIO_PROCESS
+
+typedef struct tm tm_t;
+
+#define GEAR_RATIO_ALT  75.55 // 75.25 VERY IMPORTANT! unit=RE/SE
+#define GEAR_RATIO_AZ  179.8  // VERY IMPORTANT! unit=RE/SE
+
+const XY kGearRatio(GEAR_RATIO_ALT, GEAR_RATIO_AZ);
+const XY kGearRatio2(GEAR_RATIO_ALT*16384.0/360.0, GEAR_RATIO_AZ*16384.0/360.0);
+
+double Rad2SE(double rad)
+{
+    return 16384.0/D2PI*rad;
+}
+
+double Rad2ZdRE(double rad)
+{
+    return 16384.0/D2PI*rad*kGearRatio.X();
+}
+
+double Rad2AzRE(double rad)
+{
+    return 16384.0/D2PI*rad*kGearRatio.Y();
+}
+
+double Deg2ZdRE(double rad)
+{
+    return rad*kGearRatio2.X();
+}
+
+double Deg2AzRE(double rad)
+{
+    return rad*kGearRatio2.Y();
+}
+
+ZdAz MCosy::CorrectTarget(const ZdAz &src, const ZdAz &dst)
+{
+    // CorrectTarget [se]
+
+    // src [se]
+    // dst [rad]
+
+    // fAltMax = 70
+    // fAltMin = -105/110
+    // fAzMin = -355
+    // fAzMax =  355
+
+    ZdAz source = src * 360.0/16384.0;
+    ZdAz dest   = dst * 360.0/D2PI;
+
+    if (dest.Zd()>-1e-6 && dest.Zd()<1e-6)
+        return dst*(16384.0/D2PI);
+
+    const float fZdMin = -67;
+    const float fZdMax =  67;
+    const float fAzMin = -29;
+    const float fAzMax = 423;
+
+    //
+    // This corrects to target for the shortest distance, not for the fastest move!
+    //
+    ZdAz s = source-dest;
+
+    float min = s.Sqr();
+
+    //
+    // Is it enought to search inside one revolution?
+    //
+    ZdAz ret = dest;
+
+    for (int i=-5; i<5+1; i++)
+    {
+        const ZdAz p(i%2 ? -dest.Zd() : dest.Zd(), dest.Az() - i*180);
+
+        //
+        // Range Check
+        //
+        if (p.Zd()<fZdMin || p.Zd()>fZdMax)
+            continue;
+
+        if (p.Az()<fAzMin || p.Az()>fAzMax)
+            continue;
+
+        //
+        // Calculate distance
+        //
+        s = source-p;
+
+        const float dist = s.Sqr();
+
+        if (dist > min)
+            continue;
+
+        //
+        // New shortest distance
+        //
+        ret = p;
+        min = dist;
+    }
+    return ret*(16384.0/360.0);
+}
+
+
+ZdAz MCosy::GetSePos()
+{
+    const int p0 = fAlt1->GetPos();
+    const int p1 = fAlt2->GetPos();
+    const int p2 = fAz->GetPos();
+
+    const int a0 = p0; //p0>8192?p0-16384:p0;
+    const int a1 = p1; //p1>8192?p1-16384:p1;
+    const int a2 = p2; //p2>8192?p2-16384:p2;
+
+    //
+    // interpolate shaft encoder positions
+    //
+    const float a = (float)(a0-a1)/2;
+
+    //
+    // calculate 'regelabweichung'
+    //
+    return ZdAz(a, a2);
+}
+
+ZdAz MCosy::GetRePos()
+{
+    return ZdAz(fMac2->GetPos(), fMac1->GetPos());
+}
+
+ZdAz MCosy::GetRePosPdo()
+{
+    return ZdAz(fMac2->GetPdoPos(), fMac1->GetPdoPos());
+}
+
+void MCosy::SetPosVelocity(const Float_t ratio, Float_t vel, Float_t acc)
+{
+    //
+    // Set velocities
+    //
+    const int vr = fMac1->GetVelRes();
+
+    vel *= vr;
+    acc *= vr;
+
+    if (ratio <1)
+    {
+        fMac1->SetVelocity(vel);
+        fMac1->SetAcceleration(acc);
+        fMac1->SetDeceleration(acc);
+
+        fMac2->SetVelocity(vel*ratio);
+        fMac2->SetAcceleration(acc*ratio);
+        fMac2->SetDeceleration(acc*ratio);
+    }
+    else
+    {
+        fMac1->SetVelocity(vel/ratio);
+        fMac1->SetAcceleration(acc/ratio);
+        fMac1->SetDeceleration(acc/ratio);
+
+        fMac2->SetVelocity(vel);
+        fMac2->SetAcceleration(acc);
+        fMac2->SetDeceleration(acc);
+    }
+}
+
+void MCosy::DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2)
+{
+    SetStatus(kMoving);
+
+    if (axe1) fMac2->StartRelPos(rd.Zd());
+    if (axe2) fMac1->StartRelPos(rd.Az());
+
+    cout << "Waiting for positioning..." << flush;
+
+    WaitForEndMovement();
+
+    cout << "done." << endl;
+}
+
+void MCosy::CheckForError()
+{
+    if (!HasError())
+    {
+        SetStatus(kStopped);
+        return;
+    }
+
+    SetStatus(kError);
+    fMac1->HandleError();
+    fMac2->HandleError();
+    if (HasError())
+        return;
+
+    SetStatus(kStopped);
+}
+
+int MCosy::SetPosition(const ZdAz &dst) // [rad]
+{
+    // FIXME: Correct by fOffset ?
+
+    //
+    // Calculate new target position (shortest distance to go)
+    //
+    const ZdAz src  = GetSePos();
+    const ZdAz dest = CorrectTarget(src, dst);
+
+    lout << "Positioning to Target..." << 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 << "Shortest Dest Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
+
+    for (int i=0; i<10 && !StopWaitingForSDO(); i++)
+    {
+        //
+        // Get Shaft Encoder Positions
+        //
+        const ZdAz p=GetSePos();
+
+        //
+        // calculate control deviation and rounded cd
+        //
+        ZdAz rd = dest-p; // [se]
+
+        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)
+        {
+            lout << "Positioning done with " << i << "manuvers." << endl;
+            return TRUE;
+        }
+
+        //
+        // change units from se to re
+        //
+        rd *= kGearRatio; // [re]
+
+        //
+        // Initialize Velocities so that we reach both positions
+        // at the same time
+        //
+        if (i)
+            SetPosVelocity(1.0, 0.1, 0.1);
+        else
+            SetPosVelocity(fabs(rd.Ratio()), 0.9, 0.5);
+
+        rd.Round();
+
+        /*
+         cout << " + " << cdzd << " " << 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;
+         */
+
+        //
+        // repositioning (relative)
+        //
+        DoRelPos(rd, cdzd, cdaz);
+    }
+
+    StopMovement();
+    lout << "Warning: Requested position not reached." << endl;
+    return FALSE;
+}
+
+Bool_t MCosy::RequestRePos()
+{
+
+    fMac2->RequestSDO(0x6004);
+    fMac1->RequestSDO(0x6004);
+    WaitForSdos();
+    if (!StopWaitingForSDO())
+        return kTRUE;
+
+    if (HasError())
+        lout << "Error #6004 (requesting re pos from Macs) happened." << endl;
+
+    return kFALSE;
+}
+
+Bool_t MCosy::SetVelocity(ZdAz v)
+{
+    fMac2->SendSDO(0x3006, 1, (LWORD_t)v.Zd());  // SetRpmVelocity [re/min]
+    fMac1->SendSDO(0x3006, 1, (LWORD_t)v.Az());  // SetRpmVelocity [re/min]
+    WaitForSdos();
+    if (!StopWaitingForSDO())
+        return kTRUE;
+
+    if (HasError())
+        lout << "Error #3006 (setting velocity of Macs) happened." << endl;
+
+    return kFALSE;
+}
+
+void MCosy::InitTracking()
+{
+    //
+    // Start revolution mode
+    //
+    fMac2->SetAcceleration(0.90*fMac2->GetVelRes());
+    fMac2->SetDeceleration(0.90*fMac2->GetVelRes());
+
+    fMac1->SetAcceleration(0.90*fMac1->GetVelRes());
+    fMac1->SetDeceleration(0.90*fMac1->GetVelRes());
+
+    SetStatus(kMoving | kTracking);
+
+    fMac2->SetRpmMode(TRUE);
+    fMac1->SetRpmMode(TRUE);
+}
+
+void MCosy::LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const
+{
+    //
+    // 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)
+
+    const Float_t limit = 0.25;
+
+    if (sgn(vt->Az()) != sgn(vcalc.Az()) &&
+        fabs(vt->Az()) < limit*fabs(vcalc.Az()))
+        vt->Az(0);
+    else
+        if (fabs(vt->Az()) > 0.9*vraz)
+            vt->Az(0.9*vraz*sgn(vt->Az()));
+
+    if (sgn(vt->Zd()) != sgn(vcalc.Zd()) &&
+        fabs(vt->Zd()) < limit*fabs(vcalc.Zd()))
+        vt->Zd(0);
+    else
+        if (fabs(vt->Zd()) > 0.9*vrzd)
+            vt->Zd(0.9*vrzd*sgn(vt->Zd()));
+}
+
+void MCosy::TrackPosition(const RaDec &dst) // ra, dec [rad]
+{
+    SlaStars sla;
+
+    //
+    // Position to actual position
+    //
+    sla.SetMjd2Now();
+    ZdAz dest = sla.CalcZdAz(dst);
+
+    if (!SetPosition(dest))
+    {
+        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
+    //
+    InitTracking();
+
+    lout << "Start tracking:";
+    lout << " Ra: " << Rad2Deg(dst.Ra())  << "\xb0  ";
+    lout << "Dec: " << Rad2Deg(dst.Dec()) << "\xb0" << endl;
+
+    //
+    // Initialize Tracker (slalib or starguider)
+    //
+    fRaDec    = dst;
+    fTracking = kTRUE;
+
+    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
+    //
+    const float dt = 1;  // 1 second
+    while (!StopWaitingForSDO())
+    {
+        //
+        // Request Target position for this moment
+        //
+        sla.Now();
+
+        //
+        // Request theoretical Position for a time in the future (To+dt) from CPU
+        //
+        sla.SetMjd(sla.CalcMjd()+dt/(60*60*24));
+        dest = CorrectTarget(GetSePos(), sla.CalcZdAz(dst)); // [se]
+
+        ZdAz vcalc = sla.GetApproxVel(dst) * kGearRatio2*4./60.;  // [re/min]
+
+        //
+        // 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 *= kGearRatio;  // [re]
+        dest -= GetRePos() + fOffset;
+
+        //
+        // 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/(dt-(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;
+        LimitSpeed(&vt, vcalc);
+        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
+        //
+        // usleep(50000); // 0.05s
+    }
+
+    fTracking = kFALSE;
+    StopMovement();
+    lout << "Tracking stopped." << endl;
+}
+
+int MCosy::IsPositioning() const
+{
+    return (fMac1->IsPositioning() || fMac2->IsPositioning()) && !StopWaitingForSDO();
+}
+
+void MCosy::WaitForEndMovement()
+{
+    WaitForSdos();
+
+    while (IsPositioning())
+        usleep(1);
+}
+
+void MCosy::StopMovement()
+{
+    SetStatus(kStopping);
+
+    cout << "Stopping  positioning..." << endl;
+    fMac1->SetDeceleration(0.5*fMac1->GetVelRes());
+    fMac2->SetDeceleration(0.5*fMac2->GetVelRes());
+
+    cout << "Stoping possible RPM mode..." << endl;
+    fMac1->SetRpmMode(FALSE);
+    fMac2->SetRpmMode(FALSE);
+
+    cout << "Waiting for silence..." << endl;
+    WaitForEndMovement();
+
+    CheckForError();
+
+    cout << "Movement stopped." << endl;
+}
+
+void *MCosy::Proc(int msg, void *mp)
+{
+    switch (msg)
+    {
+    case WM_WAIT:
+        cout << "Wait for execution of Proc(WM_*, ): done." << endl;
+        return NULL;
+
+    case WM_STOP:
+        StopMovement();
+        return NULL;
+
+    case WM_PRESET:
+        cout << "WM_Preset: start." << endl;
+        fAlt1->SetPreset();
+        fAlt2->SetPreset();
+        fAz->SetPreset();
+        cout << "WM_Preset: done. (return 0xaffe)" << endl;
+        return (void*)0xaffe;
+
+    case WM_POLARIS:
+        {
+            cout << "WM_Polaris: start." << endl;
+            SlaStars sla;
+            sla.SetMjd2Now();
+
+            RaDec rd(37.94, 89.2644);
+            ZdAz za=sla.CalcZdAz(rd*D2PI/360.0)*16384.0/D2PI;
+
+            cout << "Calc Zd: " << za.Zd() << " Az: " << za.Az() << endl;
+
+            ZdAz sepos = GetSePos();
+            cout << "Got  Zd: " << sepos.Zd() << " Az: " << sepos.Az() << endl;
+
+            fAlt1->SetPreset(za.Zd());
+            fAlt2->SetPreset(-za.Zd());
+            fAz->SetPreset(za.Az());
+
+            cout << "WM_Polaris: done. (return 0xaffe)" << endl;
+        }
+        return (void*)0xaffe;
+
+    case WM_POSITION:
+        cout << "WM_Position: start." << endl;
+        {
+            ZdAz dest = *((ZdAz*)mp);
+
+            SetPosition(dest*D2PI/360.0);
+        }
+        cout << "WM_Position: done. (return 0x7777)" << endl;
+        return (void*)0x7777;
+
+    case WM_TRACK:
+        cout << "WM_Track: START" << endl;
+        {
+            RaDec dest = *((RaDec*)mp);
+            TrackPosition(dest*D2PI/360.0);
+        }
+        cout << "WM_Track: done. (return 0x8888)" << endl;
+        return (void*)0x8888;
+
+    case WM_QUIT:
+        cout << "WM_Quit: now." << endl;
+        TerminateApp();
+        cout << "WM_Quit: done." << endl;
+        return (void*)0x9999;
+    }
+    cout << "Unknown Msg" << endl;
+    return (void*)0xffffffff;
+}
+
+void *MTTalk::Thread()
+{
+    fCosy->TalkThread();
+    return NULL;
+}
+
+void MCosy::TalkThread()
+{
+    //
+    // Start the Network
+    //
+    cout << "Reading configuration file..." << flush;
+    TEnv env(".cosyrc");
+    cout << "done." << endl;
+
+    const int res = fMac3->GetVelRes();
+
+    fMac3->SetVelocity(res);
+    fMac3->SetAcceleration(res);
+    fMac3->SetDeceleration(res);
+
+    fMac3->StartPosSync();
+
+    cout << "Going Home..." << endl;
+    fMac1->SetHome(250000, env.GetValue("Az_MaxTime2ReachHome[s]", 100));
+    fMac2->SetHome(250000, env.GetValue("Zd_MaxTime2ReachHome[s]", 100));
+    PostMsg(WM_PRESET, 0, 0);
+    PostMsg(WM_WAIT,   0, 0);
+
+    fMac1->ReqPos();
+    fMac2->ReqPos();
+
+    //const ZdAz repos=GetRePos();
+    //cout << "APOS: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
+
+    /*
+     cout << Deg2AzRE(env.GetValue("MinAz[Deg]", -1.0)) << " < Az < "
+     << Deg2AzRE(env.GetValue("MaxAz[Deg]", +1.0)) << "RE" << endl;
+     cout << env.GetValue("MinAz[Deg]", -1.0) << " < Az < "
+     << env.GetValue("MaxAz[Deg]", +1.0) << kDEG << endl;
+     cout << Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)) << "RE < Zd < "
+     << Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)) << "RE" << endl;
+     */
+
+    cout << "Setting up software endswitch..." << flush;
+    fMac1->SetNegEndswitch(Deg2AzRE(env.GetValue("Az_Min[Deg]", -1.0)));
+    fMac1->SetPosEndswitch(Deg2AzRE(env.GetValue("Az_Max[Deg]", +1.0)));
+
+    fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("Zd_Min[Deg]", -1.0)));
+    fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("Zd_Max[Deg]", +1.0)));
+    cout << "done." << endl;
+
+/*
+    fMac2->SetNegEndswitch(Deg2ZdRE(env.GetValue("MinZd[Deg]", -1.0)));
+    fMac2->SetPosEndswitch(Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)));
+*/
+//    fMac3->StartVelSync();
+/*
+    cout << "PostMsg(WM_PRESET)" << endl;
+    void *rc =
+    cout << hex << "WM_PRESET: ret=" << rc << endl;
+
+    RaDec dest = RaDec(45.0, 30.0)*D2PI/360.0;
+
+    cout << "PostMsg(WM_TRACK)" << endl;
+    cout << sizeof(RaDec) << "==" << sizeof(dest) << endl;
+    rc=PostMsg(WM_TRACK, &dest, sizeof(dest));
+    cout << "DEST killed." << endl;
+*/
+    // AltAz dest = AltAz(45.0, 30.0);
+    // double ra, dec;
+    // slaDaf2r( 71, 0, 0, &ra,  &status); // 0 WARNING: RANGE
+    // slaDaf2r( 89, 0, 0, &dec, &status); // 49
+    // cout << "Start tracking: Ra: " << Rad2Deg(ra) << kDEG << "  Dec: " << Rad2Deg(dec) << kDEG << endl;
+
+    // dest = AltAz(-46.0, 210);
+    // SetPosition(dest);
+
+    SlaStars sla;
+    while (1)
+    {
+        //
+        // wait until a tracking session is started
+        //
+        while (!fTracking && !fTTalk->HasStopFlag())
+            usleep(1);
+
+        if (fTTalk->HasStopFlag())
+            break;
+
+        ofstream fout("log/cosy.err");
+        fout << "Tracking:";
+        fout << " Ra: " << Rad2Deg(fRaDec.Ra())  << "\x9c  ";
+        fout << "Dec: " << Rad2Deg(fRaDec.Dec()) << "\x9c" << endl << endl;
+        fout << "     MjdZd/10ms    ErrZd/re";
+        fout << "     MjdAz/10ms    ErrAd/re" << endl;
+
+        ZdAz old;
+        ZdAz ist;
+
+        ZdAz sollzd;
+        ZdAz sollaz;
+
+        ZdAz istre = -fOffset;                // [re]
+        ZdAz time;
+
+        //
+        // only update fTrackingError while tracking
+        //
+        while (fTracking && !fTTalk->HasStopFlag())
+        {
+            //
+            // Make changes (eg wind) smoother - attenuation of control function
+            //
+            const float weight = 1.; //0.3;
+
+            ZdAz offset(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight,
+                        fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight);
+
+            fOffset = offset;
+
+            //
+            // This is the time constant which defines how fast
+            // you correct for external influences (like wind)
+            //
+            bool phca1;
+            bool phca2;
+            bool phcaz;
+
+            do
+            {
+                phca1 = fAlt1->PosHasChanged();
+                phca2 = fAlt2->PosHasChanged();
+                phcaz = fAz->PosHasChanged();
+                usleep(1);
+            } while (!phca1 && !phca2 && !phcaz);
+            //---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;
+            */
+            istre = GetRePosPdo();
+
+            //
+            // Get time from last shaftencoder position change (position: ist)
+            // FIXME: I cannot take the avarage
+            //
+            time.Zd((fAlt1->GetMjd()+fAlt2->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()*/)
+            {
+                sla.SetMjd(time.Zd());
+                sollzd = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
+            }
+
+            if (phcaz /*(int)ist.Az() != (int)old.Az()*/)
+            {
+                sla.SetMjd(time.Az());
+                sollaz = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
+            }
+
+            fTrackingError.Set((ist.Zd()-sollzd.Zd())*kGearRatio.X(),
+                               (ist.Az()-sollaz.Az())*kGearRatio.Y());
+
+            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;
+        }
+
+        fout << endl << endl;
+    }
+}
+
+Bool_t MCosy::HandleTimer(TTimer *t)
+{
+    //
+    // Update Gui, foremer MTGui.
+    //
+    fAlt1->DisplayVal();
+    fAlt2->DisplayVal();
+    fAz->DisplayVal();
+
+    ZdAz ist = GetSePos()*(360.0/16384.0); // [se]
+
+    fWin->Update(ist, fTrackingError/kGearRatio2,
+                 fVelocity, fOffset/*/kGearRatio2*/,
+                 fStatus);
+
+    return kTRUE;
+}
+
+
+int MCosy::StopWaitingForSDO() const
+{
+    return Break() || HasError();
+}
+
+void MCosy::Start()
+{
+    // Don't call this function twice!
+    Network::Start();
+
+    lout << "- Starting TX Thread." << endl;
+    fTTalk = new MTTalk(this);
+
+    lout << "- Starting GUI update." << endl;
+    fUpdateGui->TurnOn();
+    //    fTGui = new MTGui(this);
+}
+
+void MCosy::Stop()
+{
+
+    lout << "- Stopping GUI update." << endl;
+    fUpdateGui->TurnOff();
+    lout << "- GUI Update stopped." << endl;
+
+    delete fTTalk;
+    lout << "- TX Thread stopped." << endl;
+
+    Network::Stop();
+}
+
+MCosy::MCosy(const char *dev, const int baud, MLog &out)
+: Network(dev, baud, out), fTracking(kFALSE)
+{
+    //
+    // Create Nodes
+    //
+    fMac1=new Macs(1, lout);
+    fMac2=new Macs(2, lout);
+    fMac3=new Macs(3, lout);
+    fAlt1=new ShaftEncoder(4, lout);
+    fAlt2=new ShaftEncoder(5, lout);
+    fAz  =new ShaftEncoder(6, lout);
+
+    //
+    // Connect the devices to the network
+    //
+    SetNode(fMac1);
+    SetNode(fMac2);
+    SetNode(fMac3);
+    SetNode(fAlt1);
+    SetNode(fAlt2);
+    SetNode(fAz);
+
+    //
+    // Create Gui Event timer and Gui
+    //
+    fUpdateGui = new TTimer(this, 100); // 100ms
+
+    fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
+
+    fAz->SetDisplay(fWin->GetLabel1());
+    fAlt1->SetDisplay(fWin->GetLabel2());
+    fAlt2->SetDisplay(fWin->GetLabel3());
+
+    lout.SetOutputGui(fWin->GetLog(), kTRUE);
+}
+
+void MCosy::TerminateApp()
+{
+    cout << "MCosy::TerminateApp()" << endl;
+/*
+    Int_t rc;
+    TGMessageBox msg(this, gClient->GetRoot(),
+                     "Information",
+                     "Cosy is shutting down the system - this may take wa while!",
+                     kMBIconExclamation,
+                     kMBOK, //kMBClose
+                     &rc, 0);
+*/
+
+    gApplication->Terminate(0);
+}
+
+MCosy::~MCosy()
+{
+    cout << "Deleting GUI timer." << endl;
+
+    delete fUpdateGui;
+
+    cout << "Deleting Nodes." << endl;
+
+    delete fAz;
+    delete fAlt2;
+    delete fAlt1;
+    delete fMac1;
+    delete fMac2;
+    delete fMac3;
+
+    cout << "Deleting MGCosy." << endl;
+
+    lout.DisableOutputDevice(MLog::eGui);
+
+    delete fWin;
+
+    cout << "MGCosy destructed." << endl;
+}
Index: trunk/MagicSoft/Cosy/main/MCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.h	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MCosy.h	(revision 924)
@@ -0,0 +1,123 @@
+#ifndef MCOSY_H
+#define MCOSY_H
+
+#include "coord.h"
+#include "msgqueue.h"
+#include "network.h"
+#include "MThread.h"
+
+#define kDEG ((char)0x9c)  // Linux 'ø'
+
+#define WM_WAIT      WM_NULL
+#define WM_PRESET    0x1000
+#define WM_POSITION  0x1001
+#define WM_TRACK     0x1002
+#define WM_STOP      0x1003
+#define WM_POLARIS   0x1004
+#define WM_QUIT      0x1005
+
+class ShaftEncoder;
+class Macs;
+class MGCosy;
+class MCosy;
+
+class MTTalk : public MThread
+{
+private:
+    MCosy *fCosy;
+
+    void *Thread();
+
+public:
+    MTTalk(MCosy *cosy) : MThread(false), fCosy(cosy)
+    {
+        SetPriority(10);
+        Start();
+    }
+};
+
+#define kError     0x01
+#define kMoving    0x02
+#define kTracking  0x04
+#define kStopping  0x08
+#define kStopped   0x10
+
+class TTimer;
+class MCosy : public Network, public MsgQueue, public TObject
+{
+    friend class MTGui;
+    friend class MTTalk;
+
+private:
+    ShaftEncoder *fAlt1;
+    ShaftEncoder *fAlt2;
+    ShaftEncoder *fAz;
+
+    Macs *fMac1;
+    Macs *fMac2;
+    Macs *fMac3;
+
+    MGCosy *fWin;
+
+    TTimer *fUpdateGui;
+    MTTalk *fTTalk;       // should be outsourced, like the starguider.
+                          // with a generic interface to both...
+
+    ZdAz  fTrackingError; // Tracking Offset between SE and calc-pos [re]
+    ZdAz  fOffset;        // Offset between se and re coordinate system [re]
+    RaDec fRaDec;         // Position to track
+    int   fTracking;      // Flag for present tracking action
+    ZdAz  fAccuracy;      // Actual accuracy of Tracking
+    ZdAz  fVelocity;      // Actual velocity of Tracking
+
+    UInt_t fStatus;
+
+    void SetStatus(UInt_t stat) { fStatus = stat; }
+    UInt_t GetStatus() const { return fStatus; }
+
+    ZdAz GetRePos();
+    ZdAz GetRePosPdo();
+    ZdAz GetSePos();     // [se]
+
+    Bool_t RequestRePos();
+    Bool_t SetVelocity(ZdAz v);
+    void SetPosVelocity(const Float_t ratio, Float_t vel, Float_t acc);
+
+    void DoRelPos(const ZdAz &rd, const Bool_t axe1, const Bool_t axe2);
+
+    void InitTracking();
+    void LimitSpeed(ZdAz *vt, const ZdAz &vcalc) const;
+
+    void TalkThread();
+    void GuiThread(MTGui *t);
+
+    int  SetPosition(const ZdAz &dst);
+
+    void TerminateApp();
+
+    void TrackPosition(const RaDec &dst); // ra, dec [rad]
+
+    int StopWaitingForSDO() const;
+    int IsPositioning() const;
+    void CheckForError();
+
+    void StopMovement();
+    void WaitForEndMovement();
+
+public:
+    MCosy(const char *dev, const int baud, MLog &out=gLog);
+    ~MCosy();
+
+    void Start();
+    void Stop();
+
+    void *Proc(int msg, void *mp);
+
+    Bool_t HandleTimer(TTimer *t);
+
+    static ZdAz CorrectTarget(const ZdAz &src, const ZdAz &dst);
+//    static ZdAz RaDec2ZdAz(const double mjd, const RaDec &pos, const RaDec &pm=RaDec(0,0));
+
+};
+
+#endif
Index: trunk/MagicSoft/Cosy/main/MStarguider.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MStarguider.cc	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MStarguider.cc	(revision 924)
@@ -0,0 +1,95 @@
+#include "MStarguider.h"
+/*
+#include <iostream.h>
+#include <signal.h>
+
+#include <TROOT.h>
+#include <TSystem.h>
+#include <TCanvas.h>
+#include <TApplication.h>
+
+#include "timer.h"
+#include "Writer.h"
+#include "grab-v4l.h"
+#include "StarDisplay.h"
+#include "CameraDisplay.h"
+*/
+/* ---------------------------------------------------------------------- */
+/*
+void MStarguider::ReadoutLoop()
+{
+    //disp->Update();
+
+    //---    WriterPng png(768, 576);
+    //---    Writer task1(&png, 25*5/1);  // one png per five seconds
+
+    // ---
+    fCcd = new Camera;
+    CameraDisplay *task=new CameraDisplay(gClient->GetRoot());
+
+    fCcd->SetIntegrationNum(1);
+//    fCcd->Loop(task, 25*60*15); // 15min
+
+    //
+    // Stop Application Loop
+    //
+
+    //
+    // FIXME! stupid workaround for tasks without a gui!
+    //
+    //---
+    // TCanvas *c = new TCanvas("Dummy", "Dummy");
+
+//    gStopLoop= 1;
+//    while (fCcd->IsRunning())
+//        sleep(1);
+
+    delete fCcd;
+    //delete task;
+
+    gSystem->ExitLoop();
+    gSystem->DispatchOneEvent(kTRUE);
+    // ReturnFromRun(); // SetReturnFromRun();
+
+
+    cout << "Event Loop Done." << endl;
+}
+
+void *MStarguider::MapReadoutLoop(void *arg)
+{
+    MStarguider *starg = (MStarguider*)arg;
+
+    starg->ReadoutLoop();
+
+    return NULL;
+}
+
+void MStarguider::StartReadoutLoop()
+{
+    pthread_t thread;
+    if (pthread_create(&thread, NULL, MapReadoutLoop, this))
+    {
+        cout << "Error starting main thread." << endl;
+        exit(0);
+    }
+    pthread_detach(thread);
+}
+
+MStarguider::MStarguider(int *argc, char **argv, void *options=0,
+                         int numOptions=0)
+: TApplication("Starguider", argc, argv, options, numOptions), fCcd(NULL)
+{
+
+    signal(SIGINT, SignalRcvd);
+
+    //---
+
+    StartReadoutLoop();
+}
+
+MStarguider::~MStarguider()
+{
+    //---
+}
+
+*/
Index: trunk/MagicSoft/Cosy/main/MStarguider.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MStarguider.h	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MStarguider.h	(revision 924)
@@ -0,0 +1,24 @@
+#ifndef MSTARGUIDER_H
+#define MSTARGUIDER_H
+
+#include "Camera.h"
+#include "Starguider.h"
+
+class MStarguider : public Camera
+{
+private:
+    Starguider *fDisplay;
+
+public:
+    MStarguider()
+    {
+        fDisplay = new Starguider;
+    }
+
+    ~MStarguider()
+    {
+        delete fDisplay;
+    }
+};
+
+#endif
Index: trunk/MagicSoft/Cosy/main/MainCint.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MainCint.cc	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MainCint.cc	(revision 924)
@@ -0,0 +1,285 @@
+//
+// File generated by /home/tbretz/root/root/bin/rootcint at Thu Sep  6 11:48:35 2001.
+// Do NOT change. Changes will be lost next time file is generated
+//
+#include "MainCint.h"
+
+#include "TClass.h"
+#include "TBuffer.h"
+#include "TMemberInspector.h"
+#include "TError.h"
+
+#ifndef G__ROOT
+#define G__ROOT
+#endif
+
+/********************************************************
+* MainCint.cc
+********************************************************/
+
+#ifdef G__MEMTEST
+#undef malloc
+#undef free
+#endif
+
+extern "C" void G__cpp_reset_tagtableMainCint();
+
+extern "C" void G__set_cpp_environmentMainCint() {
+  G__add_compiledheader("TROOT.h");
+  G__add_compiledheader("TMemberInspector.h");
+  G__add_compiledheader("MainIncl.h");
+  G__cpp_reset_tagtableMainCint();
+}
+class G__MainCintdOcc_tag {};
+
+void* operator new(size_t size,G__MainCintdOcc_tag* p) {
+  if(p && G__PVOID!=G__getgvp()) return((void*)p);
+#ifndef G__ROOT
+  return(malloc(size));
+#else
+  return(::operator new(size));
+#endif
+}
+
+/* dummy, for exception */
+#ifdef G__EH_DUMMY_DELETE
+void operator delete(void *p,G__MainCintdOcc_tag* x) {
+  if((long)p==G__getgvp() && G__PVOID!=G__getgvp()) return;
+#ifndef G__ROOT
+  free(p);
+#else
+  ::operator delete(p);
+#endif
+}
+#endif
+
+static void G__operator_delete(void *p) {
+  if((long)p==G__getgvp() && G__PVOID!=G__getgvp()) return;
+#ifndef G__ROOT
+  free(p);
+#else
+  ::operator delete(p);
+#endif
+}
+
+void G__DELDMY_MainCintdOcc() { G__operator_delete(0); }
+
+extern "C" int G__cpp_dllrevMainCint() { return(30051503); }
+
+/*********************************************************
+* Member function Interface Method
+*********************************************************/
+
+/* Setting up global function */
+
+/*********************************************************
+* Member function Stub
+*********************************************************/
+
+/*********************************************************
+* Global function Stub
+*********************************************************/
+
+/*********************************************************
+* Get size of pointer to member function
+*********************************************************/
+class G__Sizep2memfuncMainCint {
+ public:
+  G__Sizep2memfuncMainCint() {p=&G__Sizep2memfuncMainCint::sizep2memfunc;}
+    size_t sizep2memfunc() { return(sizeof(p)); }
+  private:
+    size_t (G__Sizep2memfuncMainCint::*p)();
+};
+
+size_t G__get_sizep2memfuncMainCint()
+{
+  G__Sizep2memfuncMainCint a;
+  G__setsizep2memfunc((int)a.sizep2memfunc());
+  return((size_t)a.sizep2memfunc());
+}
+
+
+/*********************************************************
+* virtual base class offset calculation interface
+*********************************************************/
+
+   /* Setting up class inheritance */
+
+/*********************************************************
+* Inheritance information setup/
+*********************************************************/
+extern "C" void G__cpp_setup_inheritanceMainCint() {
+
+   /* Setting up class inheritance */
+}
+
+/*********************************************************
+* typedef information setup/
+*********************************************************/
+extern "C" void G__cpp_setup_typetableMainCint() {
+
+   /* Setting up typedef entry */
+   G__search_typename2("Char_t",99,-1,0,
+-1);
+   G__setnewtype(-1,"Signed Character 1 byte",0);
+   G__search_typename2("UChar_t",98,-1,0,
+-1);
+   G__setnewtype(-1,"Unsigned Character 1 byte",0);
+   G__search_typename2("Short_t",115,-1,0,
+-1);
+   G__setnewtype(-1,"Signed Short integer 2 bytes",0);
+   G__search_typename2("UShort_t",114,-1,0,
+-1);
+   G__setnewtype(-1,"Unsigned Short integer 2 bytes",0);
+   G__search_typename2("Int_t",105,-1,0,
+-1);
+   G__setnewtype(-1,"Signed integer 4 bytes",0);
+   G__search_typename2("UInt_t",104,-1,0,
+-1);
+   G__setnewtype(-1,"Unsigned integer 4 bytes",0);
+   G__search_typename2("Seek_t",105,-1,0,
+-1);
+   G__setnewtype(-1,"File pointer",0);
+   G__search_typename2("Long_t",108,-1,0,
+-1);
+   G__setnewtype(-1,"Signed long integer 4 bytes",0);
+   G__search_typename2("ULong_t",107,-1,0,
+-1);
+   G__setnewtype(-1,"Unsigned long integer 4 bytes",0);
+   G__search_typename2("Float_t",102,-1,0,
+-1);
+   G__setnewtype(-1,"Float 4 bytes",0);
+   G__search_typename2("Double_t",100,-1,0,
+-1);
+   G__setnewtype(-1,"Float 8 bytes",0);
+   G__search_typename2("Text_t",99,-1,0,
+-1);
+   G__setnewtype(-1,"General string",0);
+   G__search_typename2("Bool_t",98,-1,0,
+-1);
+   G__setnewtype(-1,"Boolean (0=false, 1=true)",0);
+   G__search_typename2("Byte_t",98,-1,0,
+-1);
+   G__setnewtype(-1,"Byte (8 bits)",0);
+   G__search_typename2("Version_t",115,-1,0,
+-1);
+   G__setnewtype(-1,"Class version identifier",0);
+   G__search_typename2("Option_t",99,-1,0,
+-1);
+   G__setnewtype(-1,"Option string",0);
+   G__search_typename2("Ssiz_t",105,-1,0,
+-1);
+   G__setnewtype(-1,"String size",0);
+   G__search_typename2("Real_t",102,-1,0,
+-1);
+   G__setnewtype(-1,"TVector and TMatrix element type",0);
+   G__search_typename2("Streamer_t",89,-1,0,
+-1);
+   G__setnewtype(-1,NULL,0);
+   G__search_typename2("VoidFuncPtr_t",89,-1,0,
+-1);
+   G__setnewtype(-1,"pointer to void function",0);
+   G__search_typename2("FreeHookFun_t",89,-1,0,
+-1);
+   G__setnewtype(-1,NULL,0);
+   G__search_typename2("ReAllocFun_t",81,-1,0,
+-1);
+   G__setnewtype(-1,NULL,0);
+   G__search_typename2("ReAllocCFun_t",81,-1,0,
+-1);
+   G__setnewtype(-1,NULL,0);
+   G__search_typename2("Axis_t",100,-1,0,
+-1);
+   G__setnewtype(-1,"Axis values type",0);
+   G__search_typename2("Stat_t",100,-1,0,
+-1);
+   G__setnewtype(-1,"Statistics type",0);
+}
+
+/*********************************************************
+* Data Member information setup/
+*********************************************************/
+
+   /* Setting up class,struct,union tag member variable */
+extern "C" void G__cpp_setup_memvarMainCint() {
+}
+/***********************************************************
+************************************************************
+************************************************************
+************************************************************
+************************************************************
+************************************************************
+************************************************************
+***********************************************************/
+
+/*********************************************************
+* Member function information setup for each class
+*********************************************************/
+
+/*********************************************************
+* Member function information setup
+*********************************************************/
+extern "C" void G__cpp_setup_memfuncMainCint() {
+}
+
+/*********************************************************
+* Global variable information setup for each class
+*********************************************************/
+extern "C" void G__cpp_setup_globalMainCint() {
+
+   /* Setting up global variables */
+   G__resetplocal();
+
+
+   G__resetglobalenv();
+}
+
+/*********************************************************
+* Global function information setup for each class
+*********************************************************/
+extern "C" void G__cpp_setup_funcMainCint() {
+   G__lastifuncposition();
+
+
+   G__resetifuncposition();
+}
+
+/*********************************************************
+* Class,struct,union,enum tag information setup
+*********************************************************/
+/* Setup class/struct taginfo */
+
+/* Reset class/struct taginfo */
+extern "C" void G__cpp_reset_tagtableMainCint() {
+}
+
+
+extern "C" void G__cpp_setup_tagtableMainCint() {
+
+   /* Setting up class,struct,union tag entry */
+}
+extern "C" void G__cpp_setupMainCint(void) {
+  G__check_setup_version(30051503,"G__cpp_setupMainCint()");
+  G__set_cpp_environmentMainCint();
+  G__cpp_setup_tagtableMainCint();
+
+  G__cpp_setup_inheritanceMainCint();
+
+  G__cpp_setup_typetableMainCint();
+
+  G__cpp_setup_memvarMainCint();
+
+  G__cpp_setup_memfuncMainCint();
+  G__cpp_setup_globalMainCint();
+  G__cpp_setup_funcMainCint();
+
+   if(0==G__getsizep2memfunc()) G__get_sizep2memfuncMainCint();
+  return;
+}
+class G__cpp_setup_initMainCint {
+  public:
+    G__cpp_setup_initMainCint() { G__add_setup_func("MainCint",(G__incsetup)(&G__cpp_setupMainCint)); G__call_setup_funcs(); }
+   ~G__cpp_setup_initMainCint() { G__remove_setup_func("MainCint"); }
+};
+G__cpp_setup_initMainCint G__cpp_setup_initializerMainCint;
+
Index: trunk/MagicSoft/Cosy/main/MainCint.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MainCint.h	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MainCint.h	(revision 924)
@@ -0,0 +1,35 @@
+/********************************************************************
+* MainCint.h
+********************************************************************/
+#ifdef __CINT__
+#error MainCint.h/C is only for compilation. Abort cint.
+#endif
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#define G__ANSIHEADER
+#define G__DICTIONARY
+#include "G__ci.h"
+extern "C" {
+extern void G__cpp_setup_tagtableMainCint();
+extern void G__cpp_setup_inheritanceMainCint();
+extern void G__cpp_setup_typetableMainCint();
+extern void G__cpp_setup_memvarMainCint();
+extern void G__cpp_setup_globalMainCint();
+extern void G__cpp_setup_memfuncMainCint();
+extern void G__cpp_setup_funcMainCint();
+extern void G__set_cpp_environmentMainCint();
+}
+
+
+#include "TROOT.h"
+#include "TMemberInspector.h"
+#include "MainIncl.h"
+
+#ifndef G__MEMFUNCBODY
+#endif
+
+
+/* STUB derived class for protected member access */
Index: trunk/MagicSoft/Cosy/main/MainIncl.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MainIncl.h	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MainIncl.h	(revision 924)
@@ -0,0 +1,3 @@
+#ifndef __CINT__
+
+#endif // __CINT__
Index: trunk/MagicSoft/Cosy/main/MainLinkDef.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MainLinkDef.h	(revision 924)
+++ trunk/MagicSoft/Cosy/main/MainLinkDef.h	(revision 924)
@@ -0,0 +1,7 @@
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#endif
Index: trunk/MagicSoft/Cosy/main/Makefile
===================================================================
--- trunk/MagicSoft/Cosy/main/Makefile	(revision 924)
+++ trunk/MagicSoft/Cosy/main/Makefile	(revision 924)
@@ -0,0 +1,52 @@
+##################################################################
+#
+#   makefile
+# 
+#   for the MARS software
+#
+##################################################################
+# @maintitle
+
+# @code
+
+#
+#  please change all system depend values in the 
+#  config.mk.${OSTYPE} file 
+#
+#
+include ../Makefile.conf.$(OSTYPE)
+include ../Makefile.conf.general
+
+# @endcode 
+
+INCLUDES = -I. -I../base -I.. -I../gui -I../catalog -I../devdrv \
+	   -I../candrv -I../incl -I../videodev
+
+# @code 
+
+CINT     = Main
+LIB      = main.a
+
+#------------------------------------------------------------------------------
+
+.SUFFIXES: .c .cc .cxx .h .hxx .o 
+
+SRCFILES = MCosy.cc \
+           MStarguider.cc
+
+SRCS    = $(SRCFILES)
+HEADERS = $(SRCFILES:.cc=.h)
+OBJS    = $(SRCFILES:.cc=.o) 
+
+############################################################
+
+all: $(LIB)
+
+include ../Makefile.rules
+
+clean:	rmlib rmcint rmobjs rmcore
+
+mrproper:	clean rmbak
+
+# @endcode
+
Index: trunk/MagicSoft/Cosy/starg.cc
===================================================================
--- trunk/MagicSoft/Cosy/starg.cc	(revision 923)
+++ trunk/MagicSoft/Cosy/starg.cc	(revision 924)
@@ -4,18 +4,18 @@
 #include <TApplication.h>
 
-#include "Starguider.h"
+#include "MGStarguider.h"
 
 /* ---------------------------------------------------------------------- */
 
-extern void InitGui();
-VoidFuncPtr_t initfuncs[] = { InitGui, 0 };
+//extern void InitGui();
+//VoidFuncPtr_t initfuncs[] = { InitGui, 0 };
 
 int main(int argc, char **argv)
 {
-    TROOT root("GUI", "GUI test environement", initfuncs);
+    TROOT root("GUI", "GUI test environement"); //, initfuncs);
 
     TApplication app("Starguider", &argc, argv);
 
-    Starguider starg;
+    MGStarguider starg;
 
     starg.Loop(0);
