Index: trunk/MagicSoft/Cosy/Changelog
===================================================================
--- trunk/MagicSoft/Cosy/Changelog	(revision 917)
+++ trunk/MagicSoft/Cosy/Changelog	(revision 918)
@@ -1,3 +1,44 @@
                                                                   -*-*- END -*-*-
+ 2001/08/29 - Thomas Bretz:
+ 
+   * MCosy.[cc,h]:
+     - added fStatus support and update
+     - added some new function to outsource some code from 
+       positioning and tracking algorithms
+     - TerminateApp now sends WM_QUIT
+     - removed comments with old GUI thread
+     -
+
+   * base/MGList.h:
+     - added DBG_MGLIST for debugging
+     
+   * devdrv/shaftencoder.[h,cc]:
+     - removed old updating thread stuff
+     
+   * gui/MGAccuracy.[h,cc]:
+     - added more accurate calculation of one dimensional
+       tracking error value
+
+   * gui/MGCoordinate.cc:
+     - removed logging statement from destructor
+     
+   * gui/MGCosy.cc:
+     - changed layout of dialog
+     - added layout manager
+     - added status frame
+     - added tabs
+     - added status display and update
+     
+   * gui/MGEmbeddedCanvas.cc:
+     - enhanced size by 1
+     
+   * gui/MGSkyPosition.cc:
+     - removed debugging output
+     
+   * gui/MGVelocity.cc:
+     - the factor 4 is now applied outside of the dialog.
+
+
+
  2001/08/23 - Thomas Bretz:
 
Index: trunk/MagicSoft/Cosy/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/MCosy.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/MCosy.cc	(revision 918)
@@ -157,4 +157,71 @@
 }
 
+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;
+
+    WaitForSdos();
+
+    cout << "SDO..." << flush;
+
+    while (fMac1->IsPositioning() || fMac2->IsPositioning() && !StopWaitingForSDO())
+        usleep(1);
+
+    cout << "done." << endl;
+
+    SetStatus(kStopped);
+}
+
+void MCosy::CheckForError()
+{
+    if (!HasError())
+        return;
+
+    SetStatus(kError);
+    fMac1->HandleError();
+    fMac2->HandleError();
+    if (HasError())
+        return;
+
+    SetStatus(kStopped);
+}
+
 int MCosy::SetPosition(const ZdAz &dst) // [rad]
 {
@@ -167,8 +234,8 @@
     const ZdAz dest = CorrectTarget(src, dst);
 
-    cout << "Positioning to Target:" << endl;
+    cout << "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;
+    //cout << "Shortest Dest Zd: " << dest.Zd() << "se  Az:" << dest.Az() << "se" << endl;
 
     for (int i=0; i<10 && !StopWaitingForSDO(); i++)
@@ -188,7 +255,13 @@
 
         //
+        // 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 (!(int)cd.Zd() && !(int)cd.Az())
+        if (!cdzd && !cdaz)
         {
             cout << "Positioning done with " << i << "manuvers." << endl;
@@ -202,67 +275,73 @@
 
         //
-        // Set velocities
-        //
-        const int vr = fMac1->GetVelRes();
-        const float maxvel = (i?0.1:0.9)*vr; // maxvel = 90%
-        const float maxacc = (i?0.1:0.5)*vr; // maxacc = 50%;
-
-        const float diff = i?1:fabs(rd.Ratio());
-
-        cout << "Salt/Saz: " << diff << endl;
-
-        if (diff <1)
-        {
-            fMac1->SetVelocity(maxvel);
-            fMac1->SetAcceleration(maxacc);
-            fMac1->SetDeceleration(maxacc);
-
-            fMac2->SetVelocity(maxvel*diff);
-            fMac2->SetAcceleration(maxacc*diff);
-            fMac2->SetDeceleration(maxacc*diff);
-        }
+        // Initialize Velocities so that we reach both positions
+        // at the same time
+        //
+        if (i)
+            SetPosVelocity(1.0, 0.1, 0.1);
         else
-        {
-            fMac1->SetVelocity(maxvel/diff);
-            fMac1->SetAcceleration(maxacc/diff);
-            fMac1->SetDeceleration(maxacc/diff);
-
-            fMac2->SetVelocity(maxvel);
-            fMac2->SetAcceleration(maxacc);
-            fMac2->SetDeceleration(maxacc);
-        }
+            SetPosVelocity(fabs(rd.Ratio()), 0.9, 0.5);
 
         rd.Round();
 
-        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 << " + " << 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)
         //
-        if ((int)cd.Zd()) fMac2->StartRelPos(rd.Zd());
-        if ((int)cd.Az()) fMac1->StartRelPos(rd.Az());
-
-        cout << "Waiting for positioning..." << flush;
-
-        WaitForSdos();
-
-        cout << "SDO..." << flush;
-
-        while (fMac1->IsPositioning() || fMac2->IsPositioning() && !StopWaitingForSDO())
-            usleep(1);
-
-        cout << "done." << endl;
+        DoRelPos(rd, cdzd, cdaz);
     }
 
-    if (StopWaitingForSDO())
-    {
-        fMac1->HandleError();
-        fMac2->HandleError();
-    }
+    CheckForError();
 
     cout << "Positioning ERROR!" << endl;
     return FALSE;
+}
+
+Bool_t MCosy::RequestRePos()
+{
+
+    fMac2->RequestSDO(0x6004);
+    fMac1->RequestSDO(0x6004);
+    WaitForSdos();
+    if (!StopWaitingForSDO())
+        return kTRUE;
+
+    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;
+
+    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);
 }
 
@@ -286,33 +365,28 @@
     // calculate offset from present se position
     //
-
     const ZdAz sepos = GetSePos()*kGearRatio;
 
-    fMac1->ReqPos();
-    fMac2->ReqPos();
-
-    const ZdAz repos=GetRePos();
-
-    fOffset = sepos-repos;
-
-    cout << "Offset: " << sepos.Zd() << "re, " << sepos.Az() << "re" << endl;
-    cout << "Offset: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
-    cout << "Offset: " << fOffset.Zd() << "re, " << fOffset.Az() << "re" << endl;
-
-    //
-    // 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());
-
-    fMac2->SetRpmMode(TRUE);
-    fMac1->SetRpmMode(TRUE);
-
-    /*-*/ int s = sla.GetSecs();
-    cout << "Start tracking: Ra: " << Rad2Deg(dst.Ra()) << kDEG << "  Dec: ";
-    cout << Rad2Deg(dst.Dec()) << kDEG << endl;
+    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();
+
+    cout << "Start tracking:";
+    cout << " Ra: " << Rad2Deg(dst.Ra())  << "deg  ";
+    cout << "Dec: " << Rad2Deg(dst.Dec()) << "deg" << endl;
 
     //
@@ -323,5 +397,5 @@
 
     ofstream fout("cosy.pos");
-    fout << "   Mjd/10ms    Offset/RE Deviation/RE V/RE/MIN/4" << endl;
+    fout << "   Mjd/10ms    V/re/min/4" << endl;
 
     //
@@ -332,5 +406,5 @@
     {
         //
-        // Request Real Position from Drive
+        // Request Target position for this moment
         //
         sla.Now();
@@ -343,26 +417,17 @@
 
         //
-        // Request absolute position of rotary encoder from MACS
-        //
-        fMac2->RequestSDO(0x6004);
-        fMac1->RequestSDO(0x6004);
-        WaitForSdos();
-        if (StopWaitingForSDO())
-        {
-            lout << "Error 6004 happened" << endl;
+        // Request absolute position of rotary encoder from Macs
+        //
+        if (!RequestRePos())
             break;
-        }
-
-        //
-        // Copy fTrackingError to a local variable
-        //
-        ZdAz offset = fOffset;
 
         //
         // distance between (To+dt) and To [re]
         // position time difference < 5usec
+        // fOffset does the synchronization between the
+        // Shaft- and the rotary encoders
         //
         dest *= kGearRatio;
-        dest -= GetRePos() + offset;
+        dest -= GetRePos() + fOffset;
 
         //
@@ -374,8 +439,12 @@
         //
         // calculate real velocity of future [re/min]
+        // believing the Macs manual '/4' shouldn't be necessary, but it is.
         //
         ZdAz vt = v/4;
         vt.Round();
 
+        //
+        // check if the drive is fast enough to follow the star
+        //
         if (v.Zd()>.9*fMac1->GetVelRes() || v.Az()>.9*fMac2->GetVelRes())
         {
@@ -386,44 +455,18 @@
         //
         // Set theoretical velocity (as early after calculation as possible)
-        //
-        //
         // Maybe we should attenuate the changes
         //
-        fMac2->SendSDO(0x3006, 1, (LWORD_t)vt.Zd());  // SetRpmVelocity [re/min]
-        fMac1->SendSDO(0x3006, 1, (LWORD_t)vt.Az());  // SetRpmVelocity [re/min]
-        WaitForSdos();
-        if (StopWaitingForSDO())
-        {
-            lout << "Error 3006 happened" << endl;
+        if (!SetVelocity(vt))
             break;
-        }
 
         //
         // Now do 'unnecessary' things
-        // calculate control deviation - for the moment for convinience
-        //
-
-        //if (fMac1->GetTime()-s > 1)
-        {
-            const double mjd = fMac2->GetMjd();
-            sla.SetMjd(mjd);
-            ZdAz dest0=CorrectTarget(GetSePos(), sla.CalcZdAz(dst));
-            dest0 *= kGearRatio;
-            dest0 -= GetRePos()+offset;
-            //dest0.Round();
-
-            fAccuracy = dest0/kGearRatio2; // [deg]
-            fVelocity = vt/kGearRatio2;
-
-            //cout << "Control deviation: ";
-            fout << setprecision(15) << setw(15) << mjd*60.*60.*24. << " ";
-            fout << setw(4) << (int)fTrackingError.Zd() << " ";
-            fout << setw(4) << (int)fTrackingError.Az() << " ";
-            fout << setw(4) << dest0.Zd() << " ";
-            fout << setw(4) << dest0.Az() << " ";
-            fout << setw(4) << vt.Zd()    << " ";
-            fout << setw(4) << vt.Az() << endl;
-            s = (int)fMac1->GetTime();
-        }
+        //
+        fVelocity = vt/kGearRatio2*4;
+
+        const double mjd = fMac2->GetMjd();
+        fout << setprecision(15) << setw(15) << mjd*60.*60.*24. << " ";
+        fout << setw(4) << vt.Zd() << " ";
+        fout << setw(4) << vt.Az() << endl;
 
         //
@@ -440,14 +483,14 @@
     // Stop revolution mode
     //
+    SetStatus(kStopping);
+
     fMac2->SetRpmMode(FALSE);
     fMac1->SetRpmMode(FALSE);
 
+    SetStatus(kStopped);
+
     cout << "Tracking stopped." << endl;
 
-    if (StopWaitingForSDO())
-    {
-        fMac1->HandleError();
-        fMac2->HandleError();
-    }
+    CheckForError();
 }
 
@@ -457,31 +500,33 @@
     {
     case WM_WAIT:
-        cout << "Wait for execution of Proc: done." << endl;
+        cout << "Wait for execution of Proc(WM_*, ): done." << endl;
         return NULL;
 
     case WM_STOP:
-        cout << "Stopping  positioning." << endl;
+        cout << "Stopping  positioning..." << endl;
+        SetStatus(kStopping);
         fMac1->SetDeceleration(0.5*fMac1->GetVelRes());
         fMac2->SetDeceleration(0.5*fMac2->GetVelRes());
-        cout << "Stoping" << endl;
+        cout << "Stoping possible RPM mode..." << endl;
         fMac1->SetRpmMode(FALSE);
         fMac2->SetRpmMode(FALSE);
-        cout << "Done." << endl;
+        cout << "Stopping commands sent." << endl;
         while (fMac1->IsPositioning() || fMac2->IsPositioning())
             usleep(1);
+        SetStatus(kStopped);
         cout << "Positioning stopped." << endl;
         return NULL;
 
     case WM_PRESET:
-        cout << "WM_PRESET: START" << endl;
+        cout << "WM_Preset: start." << endl;
         fAlt1->SetPreset();
         fAlt2->SetPreset();
         fAz->SetPreset();
-        cout << "WM_PRESET: DONE (return 0xaffe)" << endl;
+        cout << "WM_Preset: done. (return 0xaffe)" << endl;
         return (void*)0xaffe;
 
     case WM_POLARIS:
         {
-            cout << "WM_POLARIS: START" << endl;
+            cout << "WM_Polaris: start." << endl;
             SlaStars sla;
             sla.SetMjd2Now();
@@ -499,10 +544,10 @@
             fAz->SetPreset(za.Az());
 
-            cout << "WM_PRESET: DONE (return 0xaffe)" << endl;
+            cout << "WM_Polaris: done. (return 0xaffe)" << endl;
         }
         return (void*)0xaffe;
 
     case WM_POSITION:
-        cout << "WM_POSITION: START" << endl;
+        cout << "WM_Position: start." << endl;
         {
             ZdAz dest = *((ZdAz*)mp);
@@ -510,26 +555,26 @@
             SetPosition(dest*D2PI/360.0);
         }
-        cout << "WM_POSITION: DONE (return 0x7777)" << endl;
+        cout << "WM_Position: done. (return 0x7777)" << endl;
         return (void*)0x7777;
 
     case WM_TRACK:
-        cout << "WM_TRACK: START" << endl;
+        cout << "WM_Track: START" << endl;
         {
             RaDec dest = *((RaDec*)mp);
             TrackPosition(dest*D2PI/360.0);
         }
-        cout << "WM_TRACK: DONE (return 0x8888)" << endl;
+        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 *MTGui::Thread()
-{
-    fCosy->GuiThread(this);
-    return NULL;
-}
-*/
+
 void *MTTalk::Thread()
 {
@@ -564,6 +609,6 @@
     fMac2->ReqPos();
 
-    const ZdAz repos=GetRePos();
-    cout << "APOS: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
+    //const ZdAz repos=GetRePos();
+    //cout << "APOS: " << repos.Zd() << "re, " << repos.Az() << "re" << endl;
 
     /*
@@ -622,4 +667,5 @@
         ZdAz ist   = fTrackingError/kGearRatio;     // [se]
         ZdAz istre = fOffset;                       // [re]
+
         //
         // only update fTrackingError while tracking
@@ -691,32 +737,5 @@
     }
 }
-/*
-void MCosy::GuiThread(MTGui *t)
-{
-    fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
-
-    fAz->SetDisplay(fWin->GetLabel1());
-    fAlt1->SetDisplay(fWin->GetLabel2());
-    fAlt2->SetDisplay(fWin->GetLabel3());
-
-    while (!t->HasStopFlag())
-    {
-        usleep(100000); // 0.1s
-
-        fAlt1->DisplayVal();
-        fAlt2->DisplayVal();
-        fAz->DisplayVal();
-
-        // gSystem->ProcessEvents();
-
-        ZdAz ist = GetSePos()*(360.0/16384.0); // [se]
-        fWin->Update(ist, fAccuracy, fVelocity, fTrackingError/kGearRatio2);
-
-    }
-
-    delete fWin;
-    cout << "Not running anymore." << endl;
-}
-*/
+
 Bool_t MCosy::HandleTimer(TTimer *t)
 {
@@ -728,17 +747,9 @@
     fAz->DisplayVal();
 
-    // gSystem->ProcessEvents();
-
-    //    ZdAz err1 = fTrackingError/kGearRatio2;
-    //    ZdAz err2(30./3600., 20./3600.); // = fTrackingError/kGearRatio2;
-
-    ZdAz dummy = fOffset/kGearRatio2/4.; // /4. because using velocity canvas
-
     ZdAz ist = GetSePos()*(360.0/16384.0); // [se]
 
-    fWin->Update(ist, fTrackingError/kGearRatio2, fVelocity, dummy);
-
-    //    cout << fTrackingError.Zd()/kGearRatio2.X()*3600. << " ";
-    //    cout << fTrackingError.Az()/kGearRatio2.Y()*3600. << endl;
+    fWin->Update(ist, fTrackingError/kGearRatio2,
+                 fVelocity, fOffset/kGearRatio2,
+                 fStatus);
 
     return kTRUE;
@@ -759,5 +770,5 @@
     fTTalk = new MTTalk(this);
 
-    lout << "- Starting GUI Thread." << endl;
+    lout << "- Starting GUI update." << endl;
     fUpdateGui->TurnOn();
     //    fTGui = new MTGui(this);
@@ -766,5 +777,5 @@
 void MCosy::Stop()
 {
-    cout << "Stopping Gui Timer Events." << endl;
+    cout << "- Stopping GUI update." << endl;
     fUpdateGui->TurnOff();
     //    delete fTGui;
@@ -831,4 +842,6 @@
 MCosy::~MCosy()
 {
+    cout << "Deleting GUI timer." << endl;
+
     delete fUpdateGui;
 
@@ -846,4 +859,4 @@
     delete fWin;
 
-    cout << "MGCosy deleted." << endl;
-}
+    cout << "MGCosy destructed." << endl;
+}
Index: trunk/MagicSoft/Cosy/MCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/MCosy.h	(revision 917)
+++ trunk/MagicSoft/Cosy/MCosy.h	(revision 918)
@@ -15,4 +15,5 @@
 #define WM_STOP      0x1003
 #define WM_POLARIS   0x1004
+#define WM_QUIT      0x1005
 
 class ShaftEncoder;
@@ -20,21 +21,4 @@
 class MGCosy;
 class MCosy;
-
-/*
-class MTGui : public MThread
-{
-private:
-    MCosy *fCosy;
-
-    void *Thread();
-
-public:
-    MTGui(MCosy *cosy) : MThread(false), fCosy(cosy)
-    {
-        SetPriority(20);
-        Start();
-    }
-};
-*/
 
 class MTTalk : public MThread
@@ -53,4 +37,11 @@
     }
 };
+
+#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
@@ -71,7 +62,6 @@
 
     TTimer *fUpdateGui;
-
-    //MTGui  *fTGui;
-    MTTalk *fTTalk;
+    MTTalk *fTTalk;       // should be outsourced, like the starguider.
+                          // with a generic interface to both...
 
     ZdAz  fTrackingError; // Tracking Offset between SE and calc-pos [re]
@@ -82,7 +72,20 @@
     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 TalkThread();
@@ -96,4 +99,5 @@
 
     int StopWaitingForSDO() const;
+    void CheckForError();
 
 public:
Index: trunk/MagicSoft/Cosy/ToDo
===================================================================
--- trunk/MagicSoft/Cosy/ToDo	(revision 917)
+++ trunk/MagicSoft/Cosy/ToDo	(revision 918)
@@ -8,3 +8,5 @@
    shaftencoder position changed (recalc fOffset, fTracking Error
    as often as possible)
+   
+ - Check why it crashes if you exit the program while 'going home'
 
Index: trunk/MagicSoft/Cosy/base/MGList.h
===================================================================
--- trunk/MagicSoft/Cosy/base/MGList.h	(revision 917)
+++ trunk/MagicSoft/Cosy/base/MGList.h	(revision 918)
@@ -2,5 +2,7 @@
 #define MGLIST_H
 
+#ifdef DBG_MGLIST
 #include <iostream.h>
+#endif
 
 #ifndef ROOT_TOrdCollection
@@ -13,5 +15,7 @@
     ~MGList()
     {
+#ifdef DBG_MGLIST
         cout << "Deleting:" << flush;
+#endif
 
         TIter Next(this);
@@ -20,8 +24,12 @@
         while ((obj=Next()))
         {
+#ifdef DBG_MGLIST
             cout << " <" << ((TGObject*)obj)->GetName() << ">" << flush;
+#endif
             delete (TGObject*)obj;
         }
+#ifdef DBG_MGLIST
         cout << endl;
+#endif
     }
     void Add(TGObject *obj)
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 918)
@@ -15,14 +15,8 @@
 ShaftEncoder::ShaftEncoder(BYTE_t nodeid, ostream &out=cout) : NodeDrv(nodeid, out), fLabel(NULL)
 {
-    //
-    // Show information
-    //
-    //    pthread_create(&fThread, NULL, MapUpdateThread, this);
-
 }
 
 ShaftEncoder::~ShaftEncoder()
 {
-    //    pthread_cancel(fThread);
 }
 
@@ -91,20 +85,5 @@
     cout << endl;
 }
-/*
-void *ShaftEncoder::MapUpdateThread(void *data)
-{
-    ShaftEncoder *se = (ShaftEncoder*) data;
-
-    //
-    // Detach thread (make sure that it is really removed from memory)
-    //
-    pthread_detach(pthread_self());
-    setpriority(PRIO_PROCESS, 0, 5);
-
-    se->UpdateThread();
-
-    return NULL;
-}
-*/
+
 void ShaftEncoder::DisplayVal()
 {
@@ -133,35 +112,5 @@
     }
 }
-/*
-void ShaftEncoder::UpdateThread()
-{
-    return;
-    //
-    // check for a running thread and lock mutex
-    //
-
-    //
-    // Wait until the network and the output widget is initialized
-    //
-    while (!GetNetwork() || !fLabel)
-        usleep(1);
-
-    while (1)
-    {
-        usleep(40000);
-        //WaitForNextPdo1();
-
-        //
-        // Update information
-        //
-
-
-        //
-        // make updated information visible
-        //
-        //gSystem->ProcessEvents(); ----> MCosy::GuiThread
-    }
-}
-*/
+
 void ShaftEncoder::HandlePDOType0(BYTE_t *data)
 {
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 917)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 918)
@@ -4,6 +4,4 @@
 #include "timer.h"
 #include "nodedrv.h"
-
-#include <pthread.h>
 
 class TGLabel;
@@ -22,8 +20,4 @@
 
     Timer fTime;
-
-    //    pthread_t fThread;
-    //    static void *MapUpdateThread(void *se);
-    //    void UpdateThread();
 
     void HandlePDOType0(BYTE_t *data);
Index: trunk/MagicSoft/Cosy/gui/MGAccuracy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 918)
@@ -58,4 +58,8 @@
     line.DrawLine(    0, -65*4,    0, 65*4);
 
+    //
+    // Can be replaced by TGaxis axe; in a later root version
+    // than 3.01/06. I talked to Rene
+    //
     TGaxis *axe;
     axe = new TGaxis(-60*4,   0, 60*4,  0,  -4, 4, 30204, "+-N");
@@ -175,34 +179,26 @@
 MGAccuracy::~MGAccuracy()
 {
-    cout << "MGAccuracy destroyed." << endl;
-}
-
-void MGAccuracy::UpdateText(Float_t x, Float_t y)
-{
-    /*
-     int xs = (int)floor(fmod(fabs(x), 60.));
-     int ys = (int)floor(fmod(fabs(y), 60.));
-     x /= 60.;
-     y /= 60.;
-     int xm = (int)floor(fmod(fabs(x), 60.));
-     int ym = (int)floor(fmod(fabs(y), 60.));
-
-     char tx[100];
-     char ty[100];
-
-     xm ? sprintf(tx, "%d'%02d\"", xm, xs) : sprintf(tx, "%d\"", xs);
-     ym ? sprintf(ty, "%d'%02d\"", ym, ys) : sprintf(ty, "%d\"", ys);
-
-     char txt[200];
-     sprintf(txt, "%s / %s", tx, ty);
-     */
-
-    // FIXME: We are on a sphere
-
-    float r = sqrt(x*x+y*y);
-
-    int rs = (int)floor(fmod(r, 60.));
-    r /= 60.;
-    int rm = (int)floor(fmod(r, 60.));
+    //    cout << "MGAccuracy destroyed." << endl;
+}
+
+void MGAccuracy::UpdateText(Float_t pzd, Float_t azd, Float_t aaz)
+{
+    const Float_t d2r = TMath::Pi()/360.;
+
+    pzd *= d2r;
+    azd *= d2r;
+    aaz *= d2r;
+
+    const float dphi2 = aaz/2.;
+    const float cos2  = cos(dphi2)*cos(dphi2);
+    const float sin2  = sin(dphi2)*sin(dphi2);
+
+    float dist = acos(cos(azd)*cos2 - cos(2*pzd+azd)*sin2);
+
+    dist *= 3600./d2r;
+
+    int rs = (int)floor(fmod(dist, 60.));
+    dist /= 60.;
+    int rm = (int)floor(fmod(dist, 60.));
 
     char txt[100];
@@ -227,5 +223,5 @@
 }
 
-void MGAccuracy::Update(ZdAz &zdaz)
+void MGAccuracy::Update(ZdAz &pos, ZdAz &acc)
 {
     //
@@ -235,6 +231,6 @@
     static int Y = ~0;
 
-    float x = zdaz.Az()*3600.; // ["]
-    float y = zdaz.Zd()*3600.; // ["]
+    float x = acc.Az()*3600.; // ["]
+    float y = acc.Zd()*3600.; // ["]
 
     int pixx = (int)(x/fPix);  // [pix]
@@ -248,5 +244,5 @@
 
     UpdateCross(x, y);
-    UpdateText(x, y);
+    UpdateText(pos.Zd(), acc.Az(), acc.Zd());
 
     SetModified();
Index: trunk/MagicSoft/Cosy/gui/MGAccuracy.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGAccuracy.h	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGAccuracy.h	(revision 918)
@@ -32,5 +32,5 @@
     void InitCross();
 
-    void UpdateText(Float_t x, Float_t y);
+    void UpdateText(Float_t zd, Float_t x, Float_t y);
     void UpdateCross(Float_t x, Float_t y);
 
@@ -39,5 +39,5 @@
     ~MGAccuracy();
 
-    void Update(ZdAz &pos);
+    void Update(ZdAz &pos, ZdAz &acc);
 };
 
Index: trunk/MagicSoft/Cosy/gui/MGCoordinate.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCoordinate.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGCoordinate.cc	(revision 918)
@@ -126,5 +126,5 @@
 MGCoordinate::~MGCoordinate()
 {
-    cout << "MGCoordinate destroyed." << endl;
+    //    cout << "MGCoordinate destroyed." << endl;
 }
 
Index: trunk/MagicSoft/Cosy/gui/MGCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 918)
@@ -1,8 +1,11 @@
 #include "MGCosy.h"
 
+#include <iostream.h>
+
 #include "msgqueue.h"
 
 #include <TROOT.h>
 
+#include <TGTab.h>         // TGTab
 #include <TGMenu.h>        // TGPopupMenu
 #include <TGButton.h>      // TGButton
@@ -10,4 +13,5 @@
 #include <TGLabel.h>       // TGLabel
 #include <TG3DLine.h>      // TGHorizontal3DLine (TGSplitter)
+#include <TGFrame.h>       // TGGroupFrame
 #include <TApplication.h>  // gApplication
 
@@ -31,4 +35,5 @@
 #define kPB_CALCALTAZ 0x1004
 #define kPB_POLARIS   0x1005
+#define kPB_START     0x1006
 
 #define kEF_A         0x1010
@@ -43,7 +48,7 @@
     //  crate the menu bar
     //
-    TGPopupMenu *fFileMenu = new TGPopupMenu(fClient->GetRoot());
+    TGPopupMenu *fFileMenu = new TGPopupMenu(gClient->GetRoot());
     fFileMenu->AddEntry ("Exit", IDM_EXIT) ;
-    fFileMenu->Associate(this);
+    //fFileMenu->Associate(this);
     fList->Add(fFileMenu);
 
@@ -53,92 +58,183 @@
     TGMenuBar *fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
     fMenuBar->AddPopup("File", fFileMenu, fLayMenuItem);
-    AddFrame(fMenuBar);
+    AddFrame(fMenuBar, fLayMenuBar);
     fList->Add(fMenuBar);
 
     //
-    //  Seperator beyonf menubar
-    //
+    //  Seperator beyond menubar
+    //
+
     TGHorizontal3DLine *fLineSep = new TGHorizontal3DLine(this);
     AddFrame(fLineSep, fLayMenuBar);
     fList->Add(fLineSep);
-
-}
-
-void MGCosy::CreateLabel()
-{
+}
+
+void MGCosy::CreateLabel(TGCompositeFrame *f)
+{
+    const int y = 25;
+    const int x = 180;
+
     fLabel1 = new TGLabel*[3];
-    fLabel1[0] = new TGLabel(this, "00000"); // Max: 16384
+    fLabel1[0] = new TGLabel(f, "00000"); // Max: 16384
+    fLabel1[1] = new TGLabel(f, "000");   // Max: 256
+    fLabel1[2] = new TGLabel(f, "000");   // Max: 256
     fLabel1[0]->SetTextJustify(kTextRight);
-    fLabel1[0]->Move(5, 40);
+    fLabel1[1]->SetTextJustify(kTextRight);
+    fLabel1[2]->SetTextJustify(kTextRight);
+    fLabel1[0]->Move(x,    y);
+    fLabel1[1]->Move(x+43, y);
+    fLabel1[2]->Move(x+70, y);
     fList->Add(fLabel1[0]);
-    //    AddFrame(fLabel1[0], new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
-    fLabel1[1] = new TGLabel(this, "000");   // Max: 256
-    fLabel1[1]->SetTextJustify(kTextRight);
-    fLabel1[1]->Move(48, 40);
     fList->Add(fLabel1[1]);
-    //    AddFrame(fLabel1[1], new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
-    fLabel1[2] = new TGLabel(this, "000");   // Max: 256
-    fLabel1[2]->SetTextJustify(kTextRight);
-    fLabel1[2]->Move(75, 40);
     fList->Add(fLabel1[2]);
-    //    AddFrame(fLabel1[2], new TGLayoutHints(kLHintsNormal, 9, 9, 9, 9));
+    //f->AddFrame(fLabel1[0]);
+    //f->AddFrame(fLabel1[1]);
+    //f->AddFrame(fLabel1[2]);
 
     fLabel2 = new TGLabel*[3];
-    fLabel2[0] = new TGLabel(this, "00000");
+    fLabel2[0] = new TGLabel(f, "00000");
+    fLabel2[1] = new TGLabel(f, "000");
+    fLabel2[2] = new TGLabel(f, "000");
     fLabel2[0]->SetTextJustify(kTextRight);
-    fLabel2[0]->Move(5, 60);
+    fLabel2[1]->SetTextJustify(kTextRight);
+    fLabel2[2]->SetTextJustify(kTextRight);
+    fLabel2[0]->Move(x,    y+20);
+    fLabel2[1]->Move(x+43, y+20);
+    fLabel2[2]->Move(x+70, y+20);
     fList->Add(fLabel2[0]);
-    //    AddFrame(fLabel2[0], new TGLayoutHints); //(kLHintsNormal, 0, 0, 0, 0));
-    fLabel2[1] = new TGLabel(this, "000");
-    fLabel2[1]->SetTextJustify(kTextRight);
-    fLabel2[1]->Move(48, 60);
     fList->Add(fLabel2[1]);
-    //    AddFrame(fLabel2[1], new TGLayoutHints); //(kLHintsNormal, 1, 0, 0, 0));
-    fLabel2[2] = new TGLabel(this, "000");
-    fLabel2[2]->SetTextJustify(kTextRight);
-    fLabel2[2]->Move(75, 60);
     fList->Add(fLabel2[2]);
-    //    AddFrame(fLabel2[2], new TGLayoutHints); //(kLHintsNormal, 2, 0, 0, 0));
+    //f->AddFrame(fLabel2[0]);
+    //f->AddFrame(fLabel2[1]);
+    //f->AddFrame(fLabel2[2]);
 
     fLabel3 = new TGLabel*[3];
-    fLabel3[0] = new TGLabel(this, "00000");
+    fLabel3[0] = new TGLabel(f, "00000");
+    fLabel3[1] = new TGLabel(f, "000");
+    fLabel3[2] = new TGLabel(f, "000");
     fLabel3[0]->SetTextJustify(kTextRight);
-    fLabel3[0]->Move(5, 80);
+    fLabel3[1]->SetTextJustify(kTextRight);
+    fLabel3[2]->SetTextJustify(kTextRight);
+    fLabel3[0]->Move(x,    y+40);
+    fLabel3[1]->Move(x+43, y+40);
+    fLabel3[2]->Move(x+70, y+40);
     fList->Add(fLabel3[0]);
-    //    AddFrame(fLabel3[0]); //, new TGLayoutHints(kLHintsNormal, 0, 0, 0, 0));
-    fLabel3[1] = new TGLabel(this, "000");
-    fLabel3[1]->SetTextJustify(kTextRight);
-    fLabel3[1]->Move(48, 80);
     fList->Add(fLabel3[1]);
-    //    AddFrame(fLabel3[1]); //, new TGLayoutHints(kLHintsNormal, 1, 0, 0, 0));
-    fLabel3[2] = new TGLabel(this, "000");
-    fLabel3[2]->SetTextJustify(kTextRight);
-    fLabel3[2]->Move(75, 80);
     fList->Add(fLabel3[2]);
-    //    AddFrame(fLabel3[2]); //, new TGLayoutHints(kLHintsNormal, 2, 0, 0, 0));
-}
-
-void MGCosy::CreateButton()
-{
-    TGTextButton *fButton1 = new TGTextButton(this, "Position Zd/Az", kPB_POSITION);
-    TGTextButton *fButton2 = new TGTextButton(this, "Track   Ra/Dec", kPB_TRACK);
-    TGTextButton *fButton3 = new TGTextButton(this, "Stop",           kPB_STOP);
-    TGTextButton *fButton4 = new TGTextButton(this, "Calc     Zd/Az", kPB_CALCALTAZ);
-    TGTextButton *fButton5 = new TGTextButton(this, "Set Polaris",    kPB_POLARIS);
-    fButton1->Move(110,  40);
-    fButton2->Move(110,  65);
-    fButton3->Move(260,  90);
-    fButton4->Move(110,  90);
-    fButton5->Move(110, 115);
-    fButton1->SetToolTipText("Move Telescope to Zd/Az position.");
-    fButton2->SetToolTipText("Track the coordinates given in Ra/Dec.");
-    fButton3->SetToolTipText("Stop movement of telescope.");
+    //f->AddFrame(fLabel3[0]);
+    //f->AddFrame(fLabel3[1]);
+    //f->AddFrame(fLabel3[2]);
+
+
+    fError    = new TGLabel(f, "Error");
+    fMoving   = new TGLabel(f, "Moving");
+    fTracking = new TGLabel(f, "Tracking");
+    fStopping = new TGLabel(f, "Stopping");
+    fStopped  = new TGLabel(f, "Stopped");
+
+    fError   ->SetBackgroundColor(224); // red
+    fMoving  ->SetBackgroundColor(10);  // blue
+    fTracking->SetBackgroundColor(47);  // blue
+    fStopping->SetBackgroundColor(164); // orange
+    fStopped ->SetBackgroundColor(20);  // green
+
+    fError   ->Move(10, 25);
+    fMoving  ->Move(10, 25+20);
+    fTracking->Move(10, 25+40);
+    fStopping->Move(10, 25+60);
+    fStopped ->Move(10, 25+80);
+
+    fError   ->Resize(60, 20);
+    fMoving  ->Resize(60, 20);
+    fTracking->Resize(60, 20);
+    fStopping->Resize(60, 20);
+    fStopped ->Resize(60, 20);
+
+    fList->Add(fError);
+    fList->Add(fMoving);
+    fList->Add(fTracking);
+    fList->Add(fStopping);
+    fList->Add(fStopped);
+}
+
+void MGCosy::CreateButton(TGCompositeFrame *tf1, TGCompositeFrame *tf2)
+{
+    const int x=15;
+    const int y=12;
+    const int h=16;
+
+    TGLabel *l1 = new TGLabel(tf1, "Move the telescope to a position given in");
+    TGLabel *l2 = new TGLabel(tf1, "local coordinates. The given coordinates");
+    TGLabel *l3 = new TGLabel(tf1, "are pointing coordinates, which means that the");
+    TGLabel *l4 = new TGLabel(tf1, "coordinates are corrected for the bending of");
+    TGLabel *l5 = new TGLabel(tf1, "the telescope."); 
+    l1->Move(x, y);
+    l2->Move(x, y+h);
+    l3->Move(x, y+2*h);
+    l4->Move(x, y+3*h);
+    l5->Move(x, y+4*h);
+    fList->Add(l1);
+    fList->Add(l2);
+    fList->Add(l3);
+    fList->Add(l4);
+    fList->Add(l5);
+
+    l1 = new TGLabel(tf2, "Track a position given in sky coordinates.");
+    l2 = new TGLabel(tf2, "Right Ascension and declination must be given");
+    l3 = new TGLabel(tf2, "in the FK5, J2000 coordinate system");
+    l1->Move(x, y);
+    l2->Move(x, y+h);
+    l3->Move(x, y+2*h);
+    fList->Add(l1);
+    fList->Add(l2);
+    fList->Add(l3);
+
+    //
+    // light green: 3   light red:  2   blue?:      2
+    // dark green:  8   dark red:  50   dark blue?: 1
+
+    //
+    // blue:  0-7, 9, 10,11, 14, 15, 18, 19, 22, 23, 27, 31, 33-39, 41-43
+    //        46, 47
+    // green: 8, 12,13, 16, 17, 20, 21, 24, 25, 26, 28, 29, 30, 40, 44
+    //        45, 48
+    // gray:  31, 113-
+    // red:   164, 192, 224, 232
+    //
+
+    //    TGTextButton *fButton1 = new TGTextButton(this, "Position Zd/Az", kPB_POSITION);
+    //    TGTextButton *fButton2 = new TGTextButton(this, "Track   Ra/Dec", kPB_TRACK);
+    TGTextButton *fButton4 = new TGTextButton(this, "Calc Zd/Az",  kPB_CALCALTAZ);
+    TGTextButton *fButton5 = new TGTextButton(this, "Set Polaris", kPB_POLARIS);
+    //    fButton1->Move(120,  40);
+    //    fButton2->Move(120,  65);
+    fButton4->Resize(80, 25);
+    fButton5->Resize(80, 25);
+
+    fButton4->Move(40, 257);
+    fButton5->Move(40, 288);
+    //fButton4->SetBackgroundColor(12);
+    //fButton5->SetBackgroundColor(16);
+    //    fButton1->SetToolTipText("Move Telescope to Zd/Az position.");
+    //    fButton2->SetToolTipText("Track the coordinates given in Ra/Dec.");
     fButton4->SetToolTipText("Calculate Zd/Az corresponding to Ra/Dec.");
     fButton5->SetToolTipText("Set the actual position as the position of Polaris.");
-    fList->Add(fButton1);
-    fList->Add(fButton2);
-    fList->Add(fButton3);
+    //    fList->Add(fButton1);
+    //    fList->Add(fButton2);
     fList->Add(fButton4);
     fList->Add(fButton5);
+
+    TGTextButton *fStart = new TGTextButton(this, "Start", kPB_START);
+    TGTextButton *fStop  = new TGTextButton(this, "Stop",  kPB_STOP);
+    fStart->SetBackgroundColor(20);
+    fStop ->SetBackgroundColor(224);
+    fStart->Move(147, 275);
+    fStop ->Move(212, 275);
+    fStart->Resize(60, 25);
+    fStop ->Resize(60, 25);
+    fStart->SetToolTipText("Start a telescope movement.");
+    fStop ->SetToolTipText("Stop any movement of telescope.");
+    fList->Add(fStart);
+    fList->Add(fStop);
 }
 
@@ -149,41 +245,63 @@
 
     CreateMenu();
-    CreateLabel();
-    CreateButton();
-
+
+    TGCompositeFrame *f = new TGCompositeFrame(this, 0, 0);
+    f->SetLayoutManager(new TGMatrixLayout(f, 3, 2, 10));
+    fList->Add(f);
+
+    fTab = new TGTab(f, 300, 300);
+    TGCompositeFrame *tf1 = fTab->AddTab("Position Zd/Az");
+    TGCompositeFrame *tf2 = fTab->AddTab("Track Ra/Dec");
+    fList->Add(fTab);
+
+    fSkyPosition = new MGSkyPosition(f, 300);
+    fAccuracy    = new MGAccuracy   (f, 300);
+    fVelocity    = new MGVelocity   (f, "Velocity ['/min]", 300);
+    fOffset      = new MGVelocity   (f, "Offset se-re [']", 300);
+
+    fList->Add(fSkyPosition);
+    fList->Add(fAccuracy);
+    fList->Add(fVelocity);
+    fList->Add(fOffset);
+
+    TGGroupFrame *frame = new TGGroupFrame(f, "Status");
+    frame->Resize(300, 300);
+    fList->Add(frame);
+
+    //
+    // Layout the window, tile by tile...
+    //
+    f->AddFrame(fTab);
+    f->AddFrame(fSkyPosition);
+    f->AddFrame(fAccuracy);
+    f->AddFrame(frame);
+    f->AddFrame(fVelocity);
+    f->AddFrame(fOffset);
+
+    AddFrame(f, new TGLayoutHints(kLHintsNormal | kLHintsExpandX, 0, 0, 1, 0));
+
+    //
+    // FIXME!
+    //
     fCoord = new MGCoordinates(this, kTRUE,
                                "Coordinate 1 [\xb0]:", "Coordinate 2 [\xb0]:");
-    fCoord->Move(10, 160);
+    fCoord->Move(40, 165);
     fList->Add(fCoord);
 
-    fSkyPosition = new MGSkyPosition(this, 300);
-    fSkyPosition->Move(320, 40);
-    fList->Add(fSkyPosition);
-
-    fAccuracy = new MGAccuracy(this, 300);
-    fAccuracy->Move(320, 360);
-    fList->Add(fAccuracy);
-
-    fVelocity = new MGVelocity(this, "Velocity ['/min]", 300);
-    fVelocity->Move(10, 360);
-    fList->Add(fVelocity);
-
-    fOffset = new MGVelocity(this, "Offset se-re [']", 300);
-    fOffset->Move(630, 360);
-    fList->Add(fOffset);
+    CreateButton(tf1, tf2);
+    CreateLabel(frame);
 
     //
     //   Map the window, set up the layout, etc.
     //
-    const Int_t w = 650+310;
-    const Int_t h = 690;
+    const Int_t w = 940;
+    const Int_t h = 660;
     SetWMSizeHints(w, h, w, h, 10, 10);  // set the smallest and biggest size of the Main frame
-
-    MapSubwindows();
-    Layout();
 
     SetWindowName("Cosy Main Window");
     SetIconName("Cosy");
 
+    MapSubwindows();
+    Resize(GetDefaultSize());
     MapWindow();
 }
@@ -193,5 +311,5 @@
 MGCosy::~MGCosy()
 {
-    cout << "Deleting MGCosy." << endl;
+    cout << "MGCosy::~MGCosy called." << endl;
 
     delete fLayMenuBar;
@@ -202,13 +320,43 @@
     delete fList;
 
-    cout << "MGCosy deleted." << endl;
+    cout << "MGCosy::~MGCosy done." << endl;
 }
 // ======================================================================
-void MGCosy::Update(ZdAz pos, ZdAz acc, ZdAz vel, ZdAz off)
+void MGCosy::EnableLabel(TGLabel *label, Bool_t stat)
+{
+    stat ? label->MapWindow() : label->UnmapWindow();
+
+    /*
+    TGGC *fRedTextGC(TGButton::GetDefaultGC())
+        // Set foreground color in graphics context for drawing of
+        // TGlabel and TGButtons with text in red.
+        ULong_t red;
+    gClient->GetColorByName("red", red);
+    fRedTextGC.SetForeground(red);
+    */
+}
+
+void MGCosy::Update(ZdAz pos, ZdAz acc, ZdAz vel, ZdAz off, UInt_t stat)
 {
     fSkyPosition->Update(pos);
-    fAccuracy->Update(acc);
+    fAccuracy->Update(pos, acc);
     fVelocity->Update(vel);
     fOffset->Update(off);
+
+#define kError     0x01
+#define kMoving    0x02
+#define kTracking  0x04
+#define kStopping  0x08
+#define kStopped   0x10
+
+    EnableLabel(fError,    stat&kError);
+    EnableLabel(fMoving,   stat&kMoving);
+    EnableLabel(fTracking, stat&kTracking);
+    EnableLabel(fStopping, stat&kStopping);
+    EnableLabel(fStopped,  stat&kStopped);
+
+    stat&kTracking ? fAccuracy->MapWindow() : fAccuracy->UnmapWindow();
+    stat&kTracking ? fVelocity->MapWindow() : fVelocity->UnmapWindow();
+    stat&kTracking ? fOffset->MapWindow()   : fOffset->UnmapWindow();
 }
 // ======================================================================
@@ -221,12 +369,33 @@
     // window menu item is selected.
 
-    //gSystem->ExitLoop();
-    //  gSystem->DispatchOneEvent(kTRUE);
-
-    //    TGMainFrame::CloseWindow();
-    gApplication->Terminate(0);
-}
-
-#include <iostream.h>
+    // gSystem->ExitLoop();
+    // gSystem->DispatchOneEvent(kTRUE);
+
+    // TGMainFrame::CloseWindow();
+    fQueue->PostMsg(WM_QUIT, 0, 0);
+    // gApplication->Terminate(0);
+}
+
+void MGCosy::Start(UInt_t id)
+{
+    cout << "Start " << (id?"tracking.":"positioning.") << endl;
+
+    XY xy = fCoord->GetCoordinates();
+
+    if (id)
+    {
+        RaDec dest(xy.X(), xy.Y());
+        cout << dest.Ra() << kDEG << " " << dest.Dec() << kDEG << endl;
+        fQueue->PostMsg(WM_TRACK, &dest, sizeof(dest));
+    }
+    else
+    {
+        ZdAz dest(xy.X(), xy.Y());
+        cout << dest.Zd() << kDEG << " " << dest.Az() << kDEG << endl;
+        fQueue->PostMsg(WM_POSITION, &dest, sizeof(dest));
+    }
+
+    cout << "PostMsg (" << (id?"WM_Track":"WM_Position") << ") returned." << endl;
+}
 
 Bool_t MGCosy::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
@@ -240,4 +409,8 @@
         switch (GET_SUBMSG(msg))
         {
+        case kCM_TAB:
+            //cout << "Tab: " << mp1 << endl;
+            return kTRUE;
+
         case kCM_BUTTON:
 
@@ -245,23 +418,13 @@
             {
             case kPB_POSITION:
-                cout << "Start positioning." << endl;
-                {
-                    XY xy = fCoord->GetCoordinates();
-                    ZdAz dest(xy.X(), xy.Y());
-                    cout << dest.Zd() << kDEG << " " << dest.Az() << kDEG << endl;
-                    fQueue->PostMsg(WM_POSITION, &dest, sizeof(dest));
-                }
-                cout << "PostMsg(WM_POSITION) returned." << endl;
+                Start(0);
                 return kTRUE;
 
             case kPB_TRACK:
-                cout << "Start tracking." << endl;
-                {
-                    XY xy = fCoord->GetCoordinates();
-                    RaDec dest(xy.X(), xy.Y());
-                    cout << dest.Ra() << kDEG << " " << dest.Dec() << kDEG << endl;
-                    fQueue->PostMsg(WM_TRACK, &dest, sizeof(dest));
-                }
-                cout << "PostMsg(WM_TRACK) returned." << endl;
+                Start(1);
+                return kTRUE;
+
+            case kPB_START:
+                Start(fTab->GetCurrent());
                 return kTRUE;
 
@@ -269,5 +432,5 @@
                 cout << "Sending stop movement msg." << endl;
                 fQueue->PostMsg(WM_STOP, 0, 0);
-                cout << "PostMsg(WM_STOP) returned." << endl;
+                cout << "PostMsg (WM_Stop) returned." << endl;
                 return kTRUE;
 
@@ -293,5 +456,5 @@
                 return kTRUE;
             }
-            break;
+            return kTRUE;
 
         case kCM_MENU:
@@ -300,19 +463,11 @@
             {
             case IDM_EXIT:
-                cout << "Idm_Exit." << endl;
-                CloseWindow();
-                return kTRUE;
-
-            default:
+                fQueue->PostMsg(WM_QUIT, 0, 0);
+                //cout << "Idm_Exit." << endl;
+                //CloseWindow();
                 return kTRUE;
             }
             return kTRUE;
-
-        default:
-            return kTRUE;
         }
-
-    default:
-        return kTRUE;
     }
 
Index: trunk/MagicSoft/Cosy/gui/MGCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 918)
@@ -31,4 +31,6 @@
 class MGAccuracy;
 class MGVelocity;
+class TGCompositeFrame;
+class TGTab;
 
 class MGCosy : public TGMainFrame
@@ -56,7 +58,19 @@
     MsgQueue      *fQueue;
 
+    TGTab         *fTab;
+
+    TGLabel *fError;
+    TGLabel *fMoving;
+    TGLabel *fTracking;
+    TGLabel *fStopping;
+    TGLabel *fStopped;
+
     void CreateMenu();
-    void CreateLabel();
-    void CreateButton();
+    void CreateLabel(TGCompositeFrame *f);
+    void CreateButton(TGCompositeFrame *tf1, TGCompositeFrame *tf2);
+
+    void Start(UInt_t id);
+
+    void EnableLabel(TGLabel *label, Bool_t stat);
 
 public:
@@ -70,5 +84,5 @@
     TGLabel **GetLabel3() { return fLabel3; }
 
-    void Update(ZdAz pos, ZdAz acc, ZdAz vel, ZdAz off);
+    void Update(ZdAz pos, ZdAz acc, ZdAz vel, ZdAz off, UInt_t stat);
 
     Bool_t ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2);
Index: trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.cc	(revision 918)
@@ -12,5 +12,5 @@
 MGEmbeddedCanvas::MGEmbeddedCanvas(const char *name, const TGWindow* p,
                                    const UInt_t width, Float_t range)
-    : TRootEmbeddedCanvas(name, p, width, width, kRaisedFrame),//, 0) //234, 76, kFixedSize)
+    : TRootEmbeddedCanvas(name, p, width+1, width+1, kRaisedFrame),//, 0) //234, 76, kFixedSize)
       fModified(kFALSE), fWidth(width), fRange(range), fPix(2.*range/width)
 {
@@ -33,5 +33,5 @@
     MapSubwindows();
 
-    Resize(fWidth-1, fWidth-1); //GetDefaultSize()); // ???
+    Resize(fWidth, fWidth); //GetDefaultSize()); // ???
     MapWindow();
 
@@ -44,6 +44,11 @@
         return;
 
+    //
     // FIXME: Sometimes (if the canvas couldn't be created correctly:
     // X11 Pixmap error) Update hangs the Gui system.
+    //
+    // Fixed: Using root 3.01/06 and doing the update from within the
+    // mainthread.
+    //
 
     fCanvas->Modified();
Index: trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc	(revision 918)
@@ -98,5 +98,5 @@
 {
     fText = new TText(105, 105, "");
-    fText->SetFillStyle(4000);  // transparent
+    //fText->SetFillStyle(4000);  // transparent
     fText->SetTextAlign(33);  // right, top
     fText->SetTextColor(10);  // white
@@ -323,6 +323,6 @@
         return;
 
-    cout << "Sun: x=" << x << " y=" << y;
-    cout << "   Zd=" << deg << " Az=" << 360./D2PI*zdaz.Az() << endl;
+    // cout << "Sun: x=" << x << " y=" << y;
+    // cout << "   Zd=" << deg << " Az=" << 360./D2PI*zdaz.Az() << endl;
 
     fSunL[0]->SetX1(x-3.5); fSunL[0]->SetX2(x+3.5);
Index: trunk/MagicSoft/Cosy/gui/MGVelocity.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGVelocity.cc	(revision 917)
+++ trunk/MagicSoft/Cosy/gui/MGVelocity.cc	(revision 918)
@@ -109,4 +109,8 @@
     line.DrawLine(    0, -65*2,    0, 65*2);
 
+    //
+    // Can be replaced by TGaxis axe; in a later root version
+    // than 3.01/06. I talked to Rene
+    //
     TGaxis *axe;
     axe = new TGaxis(-60*2, 0, 60*2, 0,  -2, 2,  304, "+-N");
@@ -179,10 +183,8 @@
 MGVelocity::~MGVelocity()
 {
-    delete fList;
-
     delete fOld;
     delete fAvg;
 
-    cout << "MGVelocity destroyed." << endl;
+    //    cout << "MGVelocity destroyed." << endl;
 }
 
@@ -270,6 +272,6 @@
     //    static int Y = 0xaffe;
 
-    float x = zdaz.Az()*3600.*4;
-    float y = zdaz.Zd()*3600.*4;
+    float x = zdaz.Az()*3600.;
+    float y = zdaz.Zd()*3600.;
 
     int pixx = (int)(x*fScale/fPix);
