Index: trunk/MagicSoft/Cosy/Changelog
===================================================================
--- trunk/MagicSoft/Cosy/Changelog	(revision 1274)
+++ trunk/MagicSoft/Cosy/Changelog	(revision 1275)
@@ -1,3 +1,77 @@
                                                                   -*-*- END -*-*-
+
+ 2002/04/12 - Thomas Bretz:
+
+   * Makefile.conf.linux-gnu:
+     - added -D_REENTRANT
+
+   * base/MThread.cc:
+     - added debug output
+
+   * candrv/canopen.cc:
+     - added debug output to destructor
+
+   * candrv/vmodican.cc:
+     - added debug output to failing read
+     - added some general debug output
+
+   * catalog/SlaStars.[h,cc]:
+     - added CalcRaDecFast
+     - added Calc*AzFast
+     - added some comments
+
+   * devdrv/macs.cc:
+     - added some HandleSDOOK output
+     - changed timer frequency to Guard Time third instead of half
+     - added some degub output
+     - changed timer to single shot timer
+     - switched off Mac timeout handling!!!
+
+   * gui/MGCosy.cc:
+     - added demo mode for 'Tag-der-Physik'
+
+   * gui/MGSkyPosition.cc:
+     - changed 'dots' to fast calculation functions
+
+   * gui/MGEmbeddedCanvas.cc:
+     - added some output
+     - fixed a bug with zero range
+
+   * main/MCosy.[h,cc]:
+     - added and changed some output
+     - changed LimitSpeed
+     - changed TalkThread
+       + only change offset when a new value for this axis is available
+       + reset the HasChanged flag before testing it
+
+
+
+ 2002/04/11 - Thomas Bretz:
+ 
+   * base/MThread.[h,cc]:
+     - added priority to constructor
+
+   * base/coord.h:
+     - added setter functions to RaDec
+
+   * base/msgqueue.[h,cc]:
+     - added some comments
+
+   * candrv/network.cc:
+     - HasError now checks all nodes
+
+   * candrv/nodedrv.[h,cc]:
+     - fixed some buggy output
+
+   * candrv/vmodican.cc:
+     - removed nonsens SetPriority (doesn't have any effect)
+
+   * gui/MGCosy.cc:
+     - replaced colors by the correct requested colors
+
+   * gui/MGSkyPosition.[h,cc]:
+     - added dots for the position in the past and future
+
+
 
  2002/04/04 - Thomas Bretz:
Index: trunk/MagicSoft/Cosy/Makefile.conf.linux-gnu
===================================================================
--- trunk/MagicSoft/Cosy/Makefile.conf.linux-gnu	(revision 1274)
+++ trunk/MagicSoft/Cosy/Makefile.conf.linux-gnu	(revision 1275)
@@ -20,5 +20,5 @@
 #
 
-OPTIM    = -O2 -Wall -fno-rtti -fno-exceptions -fPIC -Wtraditional -Wpointer-arith -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Woverloaded-virtual
+OPTIM    = -O2 -Wall -fno-rtti -fno-exceptions -fPIC -Wtraditional -Wpointer-arith -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Woverloaded-virtual -D_REENTRANT 
 DEBUG    = -g
 
Index: trunk/MagicSoft/Cosy/base/MThread.cc
===================================================================
--- trunk/MagicSoft/Cosy/base/MThread.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/base/MThread.cc	(revision 1275)
@@ -1,3 +1,5 @@
 #include <MThread.h>
+
+#include <iostream.h>
 
 #include <pthread.h>
@@ -12,9 +14,9 @@
 MThread::MThread(bool start, int prio) : fIsRunning(false), fIsDetached(false), fThread(NULL), fReturn(NULL)
 {
-    if (start)
-    {
-        SetPriority(prio);
-        Start();
-    }
+    if (!start)
+        return;
+
+    SetPriority(prio);
+    Start();
 }
 
@@ -27,6 +29,6 @@
 MThread::~MThread()
 {
-    if (fIsRunning)
-        Stop();
+    cout << "~MThread::MThread" << endl;
+    Stop();
 }
 
@@ -120,4 +122,5 @@
 void MThread::Stop()
 {
+    cout << "MThread::Stop: fThread=" << fThread << ", fIsRunning=" << (int)fIsRunning << endl;
     if (!fThread || !fIsRunning)
         return;
@@ -125,4 +128,5 @@
     if (fIsDetached)
     {
+        cout << "Stopping detached thread..." << flush;
         pthread_cancel(*fThread);
         fIsRunning = false;
@@ -130,9 +134,13 @@
     else
     {
+        cout << "Stopping thread..." << flush;
         fStop = true;
         pthread_join(*fThread, &fReturn);
     }
+    cout << "done." << endl;
 
     delete fThread;
     fThread = NULL;
+
+    cout << "MThread::Stop() done." << endl;
 }
Index: trunk/MagicSoft/Cosy/base/msgqueue.cc
===================================================================
--- trunk/MagicSoft/Cosy/base/msgqueue.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/base/msgqueue.cc	(revision 1275)
@@ -6,4 +6,8 @@
 #include <sys/resource.h>  // PRIO_PROCESS
 
+// --------------------------------------------------------------------------
+//
+// This creates the Message queue thread,
+//
 MsgQueue::MsgQueue() : fBreak(0)
 {
@@ -12,10 +16,27 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// The destructor terminates the thread.
+//
 MsgQueue::~MsgQueue()
 {
+    cout << "~MsgQueue::MsgQueue" << endl;
     pthread_cancel(fThread);
     delete (unsigned char*)fMp;
 }
 
+// --------------------------------------------------------------------------
+//
+// This is the function which must be overloaded.
+// Here you process the messages. mp is a pointer which you can
+// specify when posting the message.
+//
+// If a new messages is posted while the old one is not yet
+// finished the fBreak flag is set. Please test this flag with
+// Break() and try to finish (or stop) the current action as soon
+// as possible. This makes sure, that before a new action is started
+// the old action can be finished correctly by the user.
+//
 void *MsgQueue::Proc(int msg, void *mp)
 {
@@ -23,4 +44,8 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// This is the thread mapper.
+//
 void *MsgQueue::MapThread(void *arg)
 {
@@ -34,4 +59,11 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// This is the thread which handles the processing.
+// As soon as a message is posted the fBreak flag is set (see PostMsg)
+// And as soon as the current action is finished the new action is executed
+// in this thread. This makes sure, that the calling program is not stalled.
+//
 void MsgQueue::Thread()
 {
@@ -56,12 +88,24 @@
         pthread_mutex_unlock(&fMuxMsg);
 
+        cout << "Processing Msg 0x" << hex << fMsg << endl;
+        // --- bool quit = fMsg==WM_QUIT;
         fRc=Proc(fMsg, fMp);
+        cout << "Msg 0x" << hex << fMsg << " processed." << endl;
 
-        if (fMsg==WM_QUIT)
-            break;
+        // --- if (quit)
+        // ---    break;
+    }
 
-    }
+    // --- fStart = 0;
+    // --- cout << "WM_QUIT posted... leaving msg queue." << endl;
 }
 
+// --------------------------------------------------------------------------
+//
+// Use this function to post a message.
+// mp can be a pointer to a data structure. size should be the size of it.
+// size bytes of this structure are copied and a pointer to the copy
+// is forwarded to the Proc function.
+//
 void *MsgQueue::PostMsg(int msg, void *mp, int size)
 {
@@ -74,5 +118,7 @@
     // stopped and the messages are processed serialized
     //
+    cout << "Locking MsgQueue mutex..." << flush;
     pthread_mutex_lock(&fMuxMsg);
+    cout << "done." << endl;
 
     //
@@ -101,7 +147,11 @@
     //
     fStart = 1;
+    cout << "Releasing MsgQueue mutex..." << flush;
     pthread_mutex_unlock(&fMuxMsg);
-    while (fStart) usleep(1);
+    cout << "done." << endl;
+    while (fStart)
+        usleep(1);
 
+    cout << "Returning rc = 0x" << hex << rc << endl;
     return rc;
 }
Index: trunk/MagicSoft/Cosy/candrv/canopen.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/canopen.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/candrv/canopen.cc	(revision 1275)
@@ -67,4 +67,5 @@
             pthread_mutex_destroy(&fPdoMux[i][j]);
         }
+    lout << "- CanOpen destroyed." << endl;
 }
 
Index: trunk/MagicSoft/Cosy/candrv/vmodican.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 1275)
@@ -38,8 +38,6 @@
 #include <errno.h>         // errno
 #include <unistd.h>        // read
-#include <pthread.h>       // pthread_create
 #include <sys/time.h>      // gettimeofday
 #include <sys/ioctl.h>     // ioctl
-#include <sys/resource.h>  // PRIO_PROCESS
 
 ClassImp(VmodIcan);
@@ -110,15 +108,23 @@
     while (1)
     {
+        //
+        // Sleeps until a message arrives
+        //
         unsigned char c;
+        const int n = read(fd, &c, 1);
+
+        if (n<0)
+        {
+            cerr << "Vmodican: read(" << dec << (int)fd << "," << (void*)&c;
+            cerr << ",1) returned c=" << (int)c << " '" << strerror(errno);
+            cerr << "' (errno = " << errno << ")" << endl;
+            continue;
+            //return (void *)1;
+        }
+
+        //
+        // read the time for the message as soon as possible
+        //
         timeval_t tv;
-
-        //
-        // Sleeps until a message arrives
-        //
-        const int n = read(fd, &c, 1);
-
-        //
-        // read the time for the message as soon as possible
-        //
         gettimeofday(&tv, NULL);
 
@@ -128,5 +134,6 @@
         if (n == 0)
         {
-            cerr << "panic read (errno=" << errno << ") ..." << endl;
+            cerr << "Vmodican: Panic read '" << strerror(errno) << "' ";
+            cerr << "(errno=" << errno << ")" << endl;
             return (void *)1;
         }
@@ -155,5 +162,5 @@
 
             cout << endl;
-            break;
+            continue;
 
         //
@@ -171,7 +178,8 @@
 
             HandleMessage(&msg, &tv);
-
-            break;
+            continue;
         }
+
+        cout << "Vmodican: read, Message c=" << (int)c << " unknown." << endl;
     }
     return NULL;
@@ -495,5 +503,5 @@
 void VmodIcan::DisableCanBusConnection()
 {
-    lout << "- Disconnect from Bus!" << endl;
+    lout << "- Disconnect VmodIcan module from Bus!" << endl;
 
     Message msg;                  /* buffer for module messages */
@@ -503,4 +511,6 @@
 
     while (!Send(&msg));
+
+    lout << "- VmodIcan disconnected." << endl;
 }
 
@@ -529,5 +539,5 @@
 void VmodIcan::Close()
 {
-    lout << "- Close Device!" << endl;
+    lout << "- Closing device VmodIcan #" << (int)fd << endl;
 
     Message msg; /* disconnect message */
@@ -539,4 +549,6 @@
 
     close(fd);
+
+    lout << "- Device closed." << endl;
 }
 
@@ -950,7 +962,9 @@
 VmodIcan::~VmodIcan()
 {
+    lout << "- Stopping VmodIcan module." << endl;
     Stop();
     DisableCanBusConnection();
     Close();
+    lout << "- VmodIcan stopped." << endl;
 }
 
Index: trunk/MagicSoft/Cosy/catalog/SlaStars.cc
===================================================================
--- trunk/MagicSoft/Cosy/catalog/SlaStars.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/catalog/SlaStars.cc	(revision 1275)
@@ -40,5 +40,5 @@
     slaMappa(2000.0, mjd, fAmprms);
     slaAoppa(mjd, 0,                    // mjd, UT1-UTC
-             GetElong(), GetPhi(), 148, // gttingen long, lat, height
+             GetElong(), GetPhi(), 148, // göttingen long, lat, height
              0, 0,                      // polar motion x, y-coordinate (radians)
              273.155, 1013.25, 0.5,     // temp, pressure, humidity
@@ -69,4 +69,61 @@
 
     return RaDec(ra, dec);
+}
+
+RaDec SlaStars::CalcRaDecFast(const AltAz &altaz) const
+{
+    //
+    // This function does a coordinate system transformation only.
+    // This is very fast compared to a correct tranformation with all
+    // effects, but much less accurate.
+    //
+    // It transforms Altitude/Azimuth [rad] into
+    // Right Ascension/Declination [rad] 
+    //
+    double ha, dec;
+    slaDh2e(altaz.Az(), altaz.Alt(), GetPhi(), &ha, &dec);
+    return RaDec(GetAlpha()-ha, dec);
+}
+
+RaDec SlaStars::CalcRaDecFast(const ZdAz &zdaz) const
+{
+    //
+    // This function does a coordinate system transformation only.
+    // This is very fast compared to a correct tranformation with all
+    // effects, but much less accurate.
+    //
+    // It transforms Zenith Distance/Azimuth [rad] into
+    // Right Ascension/Declination [rad] 
+    //
+    return CalcRaDecFast(AltAz(kPiDiv2-zdaz.Zd(), zdaz.Az()));
+}
+
+ZdAz SlaStars::CalcZdAzFast(const RaDec &radec) const
+{
+    //
+    // This function does a coordinate system transformation only.
+    // This is very fast compared to a correct tranformation with all
+    // effects, but much less accurate.
+    //
+    // It transforms Right Ascension/Declination [rad] into
+    // zenith Distance/Azimuth [rad]
+    //
+    AltAz altaz = CalcAltAzFast(radec);
+    return ZdAz(kPiDiv2-altaz.Alt(), altaz.Az());
+}
+
+AltAz SlaStars::CalcAltAzFast(const RaDec &radec) const
+{
+    //
+    // This function does a coordinate system transformation only.
+    // This is very fast compared to a correct tranformation with all
+    // effects, but much less accurate.
+    //
+    // It transforms Right Ascension/Declination [rad] into
+    // Altitude/Azimuth [rad]
+    //
+    double az, el;
+    slaDe2h(GetAlpha()-radec.Ra(), radec.Dec(), GetPhi(), &az, &el);
+    return AltAz(el, az);
 }
 
Index: trunk/MagicSoft/Cosy/devdrv/macs.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 1275)
@@ -9,4 +9,22 @@
 
 ClassImp(Macs);
+
+/*
+ ---------------------------
+ For test purposes
+ ---------------------------
+
+class MyTimer : public TTimer
+{
+public:
+    MyTimer(TObject *obj, Long_t ms, Bool_t mode) : TTimer(obj, ms, mode) {}
+    Bool_t Notify()
+    {
+        cout << "Notify" << endl;
+        TTimer::Notify();
+        return kTRUE;
+    }
+};
+*/
 
 Macs::Macs(const BYTE_t nodeid, const char *name, MLog &out)
@@ -15,5 +33,5 @@
     fPosActive(0), fRpmActive(0)
 {
-    fTimeout = new TTimer(this, 100, kFALSE); // 100ms
+    fTimeout = new TTimer(this, 100, kFALSE); // 100ms, asynchronous
 }
 
@@ -102,8 +120,74 @@
 void Macs::HandleSDOOK(WORD_t idx, BYTE_t subidx)
 {
-    if (idx==0x4000 && subidx==0 && fTimerOn)
-    {
-        ResetTimeout();
-        return;
+    switch (idx)
+    {
+    case 0x2002:
+        switch (subidx)
+        {
+        case 0:
+            lout << ddev(MLog::eGui);
+            lout << "- Velocity set (" << GetNodeName() << ")" << endl;
+            lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+    case 0x2003:
+        switch (subidx)
+        {
+        case 0:
+            lout << ddev(MLog::eGui);
+            lout << "- Acceleration set (" << GetNodeName() << ")" << endl;
+            lout << edev(MLog::eGui);
+            return;
+        case 1:
+            lout << ddev(MLog::eGui);
+            lout << "- Deceleration set (" << GetNodeName() << ")" << endl;
+            lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+    case 0x3006:
+        switch (subidx)
+        {
+        case 0:
+            lout << ddev(MLog::eGui);
+            lout << "- RPM mode switched (" << GetNodeName() << ")" << endl;
+            lout << edev(MLog::eGui);
+            return;
+
+        case 1:
+            /*
+             lout << ddev(MLog::eGui);
+             lout << "- Velocity set (" << GetNodeName() << ")" << endl;
+             lout << edev(MLog::eGui);
+             */
+            return;
+        }
+        break;
+    case 0x4000:
+        if (subidx==0 && fTimerOn)
+        {
+            ResetTimeout();
+            return;
+        }
+        break;
+    case 0x6004:
+        switch (subidx)
+        {
+        case 0:
+            lout << ddev(MLog::eGui);
+            lout << "- Relative positioning started (" << GetNodeName() << ")" << endl;
+            lout << edev(MLog::eGui);
+            return;
+
+        case 1:
+            lout << ddev(MLog::eGui);
+            lout << "- Absolute positioning started (" << GetNodeName() << ")" << endl;
+            lout << edev(MLog::eGui);
+            return;
+        }
+        break;
+
+
     }
     NodeDrv::HandleSDOOK(idx, subidx);
@@ -348,5 +432,5 @@
     if (!errnum)
     {
-        cout << "Mac " << GetNodeName() << " reports Error occursion." << endl;
+        lout << "Mac " << GetNodeName() << " reports Error occursion." << endl;
         SetError(-1);
         return;
@@ -358,21 +442,21 @@
     //
     if (GetError()>0)
-        cout << "Mac " << GetNodeName() << " WARNING! Error #" << GetError() << " unhandled by software." << endl;
+        lout << GetNodeName() << " WARNING! Error #" << GetError() << " unhandled by software." << endl;
 
     SetError(errnum);
 
-    cout << "Mac " << GetNodeName() << " reports: ";
+    lout << GetNodeName() << " reports: ";
     switch (errnum)
     {
     case 6:
-        cout << "Home position not the first positioning command." << endl;
+        lout << "Home position not the first positioning command." << endl;
         return;
 
     case 8:
-        cout << "Control deviation overflow." << endl;
+        lout << "Control deviation overflow." << endl;
         return;
 
     case 9:
-        cout << "Zero index not found." << endl;
+        lout << "Zero index not found." << endl;
         return;
 
@@ -382,19 +466,19 @@
         {
         case -1:
-            cout << "Negative";
+            lout << "Negative";
             break;
         case 1:
-            cout << "Positive";
+            lout << "Positive";
             break;
         default:
-            cout << "-unknown-";
+            lout << "-unknown-";
         }
         switch (errnum)
         {
         case 11:
-            cout << " software endswitch activated." << endl;
+            lout << " software endswitch activated." << endl;
             break;
         case 25:
-            cout << " hardware endswitch activated." << endl;
+            lout << " hardware endswitch activated." << endl;
             break;
         }
@@ -402,13 +486,13 @@
 
     case 84:
-        cout << "Too many (>12) ON TIME calls." << endl;
+        lout << "Too many (>12) ON TIME calls." << endl;
         return;
 
     case 100:
-        cout << "Connection timed out." << endl;
+        lout << "Connection timed out." << endl;
         return;
 
     default:
-        cout << "Error Nr. " << errnum << ", " << errinf << endl;
+        lout << "Error Nr. " << errnum << ", " << errinf << endl;
     }
 }
@@ -436,5 +520,5 @@
     // we can go on working 'as usual' Eg. Initialize a Display Update
     //
-    cout << "Mac " << GetNodeName() << " Handling Error #" << GetError() << endl;
+    cout << GetNodeName() << " Handling Error #" << GetError() << endl;
     switch (GetError())
     {
@@ -525,8 +609,13 @@
 
         fTimerOn = kTRUE;
-        fTimeout->Start(fGuardTime, kFALSE); //kTRUE);
-
-        SendSDO(0x4000, 1, string('o', 'n'));
-        WaitForSdo(0x4000, 1);
+        fTimeout->Start(fGuardTime/*/3*2*/, kTRUE); //kFALSE); //TRUE);
+        //
+        // Start with kFALSE would be a continous timer, but this
+        // timer seems to stop it's activity at some stage without
+        // any reason
+        //
+
+//        SendSDO(0x4000, 1, string('o', 'n'));
+//        WaitForSdo(0x4000, 1);
     }
     lout << "- Timeout timer of " << GetNodeName() << " turned "
@@ -565,8 +654,17 @@
     //  FIXME! Use NMT!
     //
+    // --- lout << ddev(MLog::eGui);
+    // --- lout << "Send 0x4000: " << GetNodeName() << endl;
+
     SendSDO(0x4000, 0, (LWORD_t)0, false);
 
+    // --- lout << "Done 0x4000: " << GetNodeName() << endl;
+
     Timer time;
-    if (time.Now() > fTimeoutTime)
+
+    // --- lout << "dT " << GetNodeName() << ": " <<  dec <<(int)((fTimeoutTime-time.Now())*1000) << endl;
+    // --- lout << edev(MLog::eGui);
+
+    if (time.Now() > fTimeoutTime+0.5)
     {
         lout << ddev(MLog::eGui);
@@ -576,8 +674,13 @@
     }
 
-
     //WaitForSdo(0x4000, 0, kDontWait);
-    //    if (fTimerOn)
-    //        fTimeout->Start(fGuardTime, kTRUE);
+    //
+    // Would not be necessary if I would Start the timer with
+    // kFALSE. This would be a continous timer, but this
+    // timer seems to stop it's activity at some stage without
+    // any reason
+    //
+    if (fTimerOn)
+        fTimeout->Start(fGuardTime/*/3*2*/, kTRUE);
 
     return kTRUE;
@@ -587,12 +690,18 @@
 {
     Timer time;
-    fTimeoutTime = time.Now() + 2.*fGuardTime/1000.; //[usec]
+
+    // --- lout << ddev(MLog::eGui);
+    // --- lout << "Reset " << GetNodeName() << ": " << dec << (int)((fTimeoutTime-time.Now())*1000) << endl;
+    // --- lout << edev(MLog::eGui);
+
+    fTimeoutTime = time.Now() + 3.*fGuardTime/1000.;
 }
 
 void Macs::SetTimeoutTime(LWORD_t ms)
 {
-    fGuardTime = ms/2; // FIXME: Is '/2' the best choose?
-
-    SendSDO(0x4000, 2, ms);
+    // FIXME: Is '/2' the best choose?
+    fGuardTime = ms/3;      // how often do we send/request the handshake
+
+    SendSDO(0x4000, 2, ms); // How often do we check for the handshake
     WaitForSdo(0x4000, 2);
 }
Index: trunk/MagicSoft/Cosy/gui/MGCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 1275)
@@ -206,4 +206,5 @@
     TGCompositeFrame *tf1 = fTab->AddTab("Position Zd/Az");
     TGCompositeFrame *tf2 = fTab->AddTab("Track Ra/Dec");
+    TGCompositeFrame *tf3 = fTab->AddTab("Demo Mode");
 
     fCZdAz = new MGCoordinates(tf1, kETypeZdAz);
@@ -467,4 +468,5 @@
     cout << "Closing window - waiting until all nodes are stopped." << endl;
     fQueue->PostMsg(WM_QUIT, 0, 0);
+    cout << "Closing window - done." << endl;
     // gApplication->Terminate(0);
 }
@@ -497,4 +499,89 @@
     cout << "PostMsg (WM_Position) returned." << endl;
 }
+
+//
+// ************************** For demo purpose **********************
+//
+#include <TRandom.h>
+class MDemo : public MThread
+{
+private:
+    MsgQueue *fQueue;
+    TRandom  fRand;
+
+public:
+    MDemo() : MThread(false) {}
+
+    void SetQueue(MsgQueue *q) { fQueue = q; }
+
+    virtual void *Thread()
+    {
+        while (1)
+        {
+            Timer tm;
+            tm.Now();
+
+            Float_t h = 2.+tm.H()+(8.+tm.M())/60.;
+            RaDec dest(h*15, 130);
+
+            cout << dest.Ra()/15 << "h " << dest.Dec() << "°" << endl;
+
+            fQueue->PostMsg(WM_TRACK, &dest, sizeof(dest));
+
+            int i = 0;
+            while (!HasStopFlag() && i++<130)  // 2.5min
+                usleep(1000000);
+            if (HasStopFlag())
+                break;
+
+            //fQueue->PostMsg(WM_STOP, 0, 0);
+
+            ZdAz dest1(fRand.Integer(56)+5, fRand.Integer(360));
+
+            cout << "Demo: Zd=" << dest1.Zd() << "° Az=" << dest1.Az() << "°" << endl;
+
+            fQueue->PostMsg(WM_POSITION, &dest1, sizeof(dest1));
+
+            i = 0;
+            while (!HasStopFlag() && i++<30)  // 30s
+                usleep(1000000);
+            if (HasStopFlag())
+                break;
+
+            //ZdAz dest2(5, 30);
+            //fQueue->PostMsg(WM_POSITION, &dest2, sizeof(dest2));
+            /*
+            i = 0;
+            while (!HasStopFlag() && i++<30)  // 30s
+                usleep(1000000);
+            */
+            //if (HasStopFlag())
+            //    break;
+        }
+        cout << "Demo Thread: done." << endl;
+        return NULL;
+    }
+};
+
+MDemo demo;
+
+void MGCosy::StartDemo()
+{
+    cout << "Start Demo." << endl;
+
+    demo.SetQueue(fQueue);
+    demo.Start();
+
+    cout << "PostMsg (WM_Demo) returned." << endl;
+}
+
+void StopDemo()
+{
+    cout << "Stopping demo." << endl;
+    demo.Stop();
+}
+//
+// ******************************************************************
+//
 
 Bool_t MGCosy::ProcessMessage(Long_t msg, Long_t mp1, Long_t mp2)
@@ -526,10 +613,23 @@
              */
             case kPB_START:
-                fTab->GetCurrent() ? StartTrack() : StartPos();
+                switch (fTab->GetCurrent())
+                {
+                case 0:
+                    StartPos();
+                    return kTRUE;
+                case 1:
+                    StartTrack();
+                    return kTRUE;
+                case 2:
+                    StartDemo();
+                    return kTRUE;
+                }
                 return kTRUE;
 
             case kPB_STOP:
                 cout << "Sending stop movement msg." << endl;
+                StopDemo();
                 fQueue->PostMsg(WM_STOP, 0, 0);
+
                 cout << "PostMsg (WM_Stop) returned." << endl;
                 return kTRUE;
@@ -563,5 +663,7 @@
             {
             case IDM_EXIT:
+                cout << "IDM_EXIT: Posting WM_QUIT." << endl;
                 fQueue->PostMsg(WM_QUIT, 0, 0);
+                cout << "IDM_EXIT: WM_QUIT done." << endl;
                 //cout << "Idm_Exit." << endl;
                 //CloseWindow();
Index: trunk/MagicSoft/Cosy/gui/MGCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 1274)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 1275)
@@ -73,4 +73,5 @@
     void StartPos();
     void StartTrack();
+    void StartDemo();
 
     void EnableLabel(TGLabel *label, Bool_t stat);
Index: trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.cc	(revision 1275)
@@ -6,4 +6,6 @@
 
 #include "MGEmbeddedCanvas.h"
+
+#include <iostream.h>
 
 #include <TList.h>
@@ -17,11 +19,19 @@
       fModified(kFALSE), fWidth(width), fRange(range), fPix(2.*range/width)
 {
+    cout << "MGEmbeddedCanvas: Initializing." << endl;
     fCanvas = GetCanvas();
 
+    cout << "MGEmbeddedCanvas: fCanvas = 0x" << fCanvas << endl;
+
+    cout << "MGEmbeddedCanvas: SetFillColor." << endl;
     fCanvas->SetFillColor(39); // s. TAttFill
-    fCanvas->Range(-fRange, -fRange, fRange, fRange);
+    cout << "MGEmbeddedCanvas: fRange=" << fRange << endl;
+    if (fRange>0)
+        fCanvas->Range(-fRange, -fRange, fRange, fRange);
 
     fList = new TList;
     fList->SetOwner();
+
+    cout << "MGEmbeddedCanvas: Initializing done." << endl;
 }
 
Index: trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc	(revision 1275)
@@ -208,5 +208,5 @@
 {
     RaDec rd(radec.Ra()+off*360/24*kDeg2Rad, radec.Dec());
-    ZdAz zdaz = fSlaStar->CalcZdAz(rd);
+    ZdAz zdaz = fSlaStar->CalcZdAzFast(rd);
 
     const float s = sin(zdaz.Az());
@@ -319,5 +319,5 @@
     UpdatePlanet(kEMars,    fMars);
 
-    RaDec radec = fSlaStar->CalcRaDec(pos*kDeg2Rad);
+    RaDec radec = fSlaStar->CalcRaDecFast(pos*kDeg2Rad);
 
     UpdatePosition(radec, pos.Zd(), pos.Az());
Index: trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 1274)
+++ trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 1275)
@@ -187,5 +187,5 @@
     //
     if (HasError())
-        lout << "Error #6004 (requesting re pos from Macs) happened." << endl;
+        lout << "Error while requesting re pos from Macs (SDO #6004)" << endl;
 
     return kFALSE;
@@ -400,5 +400,6 @@
         if (!cdzd && !cdaz)
         {
-            lout << "Positioning done with " << i << "manuvers." << endl;
+            lout << "Positioning done in " << i << (i==1?" step.":" steps.") << endl;
+            SetStatus(MCosy::kStopped);
             return TRUE;
         }
@@ -468,5 +469,5 @@
     //
     if (HasError())
-        lout << "Error #3006 (setting velocity of Macs) happened." << endl;
+        lout << "Error while setting velocity (SDO #3006)" << endl;
 
     return kFALSE;
@@ -520,7 +521,31 @@
 
     const Float_t limit = 0.25;
-
-    if (sgn(vt->Az()) != sgn(vcalc.Az()) &&
-        fabs(vt->Az()) < limit*fabs(vcalc.Az()))
+/*
+    if (sgn(vt->Az()) != sgn(vcalc.Az()))
+        vt->Az(0);
+//    else
+    {
+        if (fabs(vt->Az()) < fabs(vcalc.Az()) *0.5)
+            vt->Az(0.5*vcalc.Az());
+
+        if (fabs(vt->Az()) > fabs(vcalc.Az()) *1.5)
+            vt->Az(1.5*vcalc.Az());
+    }
+
+    if (sgn(vt->Zd()) != sgn(vcalc.Zd()))
+        vt->Zd(0);
+//    else
+    {
+        if (fabs(vt->Zd()) > fabs(vcalc.Az()) *1.5)
+            vt->Zd(1.5*vcalc.Zd());
+
+        if (fabs(vt->Zd()) < fabs(vcalc.Az()) *0.5)
+            vt->Zd(0.5*vcalc.Zd());
+    }
+    */
+
+    if (sgn(vt->Az()) != sgn(vcalc.Az())
+        && fabs(vt->Az()) < limit*fabs(vcalc.Az())
+       )
         vt->Az(0);
     else
@@ -531,6 +556,7 @@
         }
 
-    if (sgn(vt->Zd()) != sgn(vcalc.Zd()) &&
-        fabs(vt->Zd()) < limit*fabs(vcalc.Zd()))
+    if (sgn(vt->Zd()) != sgn(vcalc.Zd())
+        && fabs(vt->Zd()) < limit*fabs(vcalc.Zd())
+       )
         vt->Zd(0);
     else
@@ -605,4 +631,11 @@
     {
         //
+        // The loop should not be executed faster than the ramp of
+        // a change in the velocity can be followed.
+        // (This is important on fast machines >500MHz)
+        //
+        //usleep(100000000);
+
+        //
         // Request Target position for this moment
         //
@@ -715,5 +748,5 @@
     // Stop revolution mode (movement)
     //
-    cout << "Stoping possibleRPM mode..." << endl;
+    cout << "Stopping possibleRPM mode..." << endl;
     fMac1->SetRpmMode(FALSE);
     fMac2->SetRpmMode(FALSE);
@@ -734,4 +767,5 @@
 void *MCosy::Proc(int msg, void *mp)
 {
+    cout << "MCosy::Proc: 0x" << msg << endl;
     switch (msg)
     {
@@ -846,4 +880,5 @@
      << Deg2ZdRE(env.GetValue("MaxZd[Deg]", +1.0)) << "RE" << endl;
      */
+
 
     cout << "Setting up software endswitch..." << flush;
@@ -890,9 +925,6 @@
         // wait until a tracking session is started
         //
-        while (!fTracking && !fTTalk->HasStopFlag())
+        while (!fTracking)
             usleep(1);
-
-        if (fTTalk->HasStopFlag())
-            break;
 
         ofstream fout("log/cosy.err");
@@ -915,5 +947,9 @@
         // only update fTrackingError while tracking
         //
-        while (fTracking && !fTTalk->HasStopFlag())
+        bool phca1=false;
+        bool phca2=false;
+        bool phcaz=false;
+
+        while (fTracking)
         {
             //
@@ -922,17 +958,11 @@
             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;
-
+            fZd1->ResetPosHasChanged();
+            fZd2->ResetPosHasChanged();
+            fAz->ResetPosHasChanged();
             do
             {
@@ -941,5 +971,6 @@
                 phcaz = fAz->PosHasChanged();
                 usleep(1);
-            } while (!phca1 && !phca2 && !phcaz);
+            } while (!phca1 && !phca2 && !phcaz && fTracking);
+
             //---usleep(100000); // 0.1s
 
@@ -975,4 +1006,6 @@
                 sla.SetMjd(time.Zd());
                 sollzd = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
+
+                fOffset.Zd(fOffset.Zd()*(1.-weight)+(ist.Zd()*kGearRatio.X()-istre.Zd())*weight);
             }
 
@@ -981,4 +1014,6 @@
                 sla.SetMjd(time.Az());
                 sollaz = CorrectTarget(ist, sla.CalcZdAz(fRaDec)); // [se]
+
+                fOffset.Az(fOffset.Az()*(1.-weight)+(ist.Az()*kGearRatio.Y()-istre.Az())*weight);
             }
 
@@ -1063,4 +1098,6 @@
     // Create Nodes
     //
+    lout << "- Setting up network." << endl;
+
     fMac1=new Macs(1, "Mac.1/Az",      lout);
     fMac2=new Macs(2, "Mac.2/Zd",      lout);
@@ -1084,6 +1121,8 @@
     // Create Gui Event timer and Gui
     //
+    lout << "- Initializing GUI Timer." << endl;
     fUpdateGui = new TTimer(this, 100); // 100ms
 
+    lout << "- Starting GUI." << endl;
     fWin=new MGCosy(this, gClient->GetRoot(), 1, 1);
 
@@ -1108,4 +1147,7 @@
 */
 
+    lout.DisableOutputDevice(MLog::eGui);
+    lout.SetOutputGui(NULL, kFALSE);
+
     gApplication->Terminate(0);
 }
Index: trunk/MagicSoft/Cosy/main/MCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.h	(revision 1274)
+++ trunk/MagicSoft/Cosy/main/MCosy.h	(revision 1275)
@@ -15,5 +15,4 @@
 #define WM_STOP      0x1003
 #define WM_POLARIS   0x1004
-#define WM_QUIT      0x1005
 
 class ShaftEncoder;
@@ -33,6 +32,8 @@
     {
         SetPriority(10);
+        Detach();
         Start();
     }
+    ~MTTalk() { cout << "~MTTalk::MTTalk" << endl; }
 };
 
@@ -41,5 +42,4 @@
 class MCosy : public Network, public MsgQueue, public TObject
 {
-    friend class MTGui;
     friend class MTTalk;
 
@@ -94,5 +94,4 @@
 
     void TalkThread();
-    void GuiThread(MTGui *t);
 
     int  SetPosition(const ZdAz &dst);
