Index: trunk/MagicSoft/Cosy/Changelog
===================================================================
--- trunk/MagicSoft/Cosy/Changelog	(revision 1701)
+++ trunk/MagicSoft/Cosy/Changelog	(revision 1702)
@@ -1,3 +1,48 @@
                                                                   -*-*- END -*-*-
+
+ 2003/01/13 - Thomas Bretz:
+
+   * bending.txt:
+     - changed to fit the parameters of the model
+     
+   * cosy.cc:
+     - made the 'standard mode' the default
+
+   * base/MTimeout.h:
+     - fixed the change of the base member function name of Notify
+
+   * candrv/network.[h,cc]:
+     - don't set fNodes[i] to NULL if Node is Zombie
+     - implemented HasZombie and RebootZomies
+     
+   * candrv/nodedrv.[h,cc]:
+     - implemented a base function Reboot
+     - set node to Zombie status if waitforsdo timed out
+
+   * candrv/vmodican.cc:
+     - added more precise output for CTXcon
+   
+   * devdrv/macs.[h,cc]:
+     - if first waitforsdo fails set don't go on
+     - implemented fStatus
+     - implemented enum for fStatus
+
+   * gui/MGAccuracy.cc, gui/MGSkyPosition.cc, gui/MGVelocity.cc:
+     - call SetNoContextMenu in constructor
+     
+   * gui/MGCosy.[h,cc]:
+     - some new labels
+     - implemented SetLabelColor
+     
+   * gui/MGEmbeddedCanvas.[h,cc]:
+     - implemented SetNoContextMenu
+
+   * main/MCosy.cc:
+     - exchanged all conditionals for the pointers to the nodes
+       by IsZombieNode
+     - implemented check for zombies in Proc
+
+
+
  2003/01/10 - Thomas Bretz:
 
Index: trunk/MagicSoft/Cosy/base/MTimeout.h
===================================================================
--- trunk/MagicSoft/Cosy/base/MTimeout.h	(revision 1701)
+++ trunk/MagicSoft/Cosy/base/MTimeout.h	(revision 1702)
@@ -6,5 +6,5 @@
 class MTimeout : public TTimer
 {
-    Bool_t Notify(TTimer *t)
+    Bool_t Notify()
     {
         TurnOff(); // remove from system list
Index: trunk/MagicSoft/Cosy/bending.txt
===================================================================
--- trunk/MagicSoft/Cosy/bending.txt	(revision 1701)
+++ trunk/MagicSoft/Cosy/bending.txt	(revision 1702)
@@ -1,5 +1,4 @@
 MMT 1987 July 8
 S   36   7.3622   41.448  -0.0481
-IA       136.6   -1
-IE        -45.5    -1
-END
+IA       157   -1 
+IE        -35    -1 END
Index: trunk/MagicSoft/Cosy/candrv/network.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/network.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/candrv/network.cc	(revision 1702)
@@ -240,6 +240,6 @@
             if (!fNodes[i]->IsZombieNode())
                 fNodeInitialized[i] = TRUE;
-            else
-                fNodes[i]=NULL;
+            /*else
+                fNodes[i]=NULL;*/
         }
     lout << "- All Nodes setup." << endl;
@@ -288,2 +288,38 @@
     return rc;
 }
+
+// --------------------------------------------------------------------------
+//
+// returns true if one of the nodes is a zombie node
+//
+bool Network::HasZombie() const
+{
+    for (int i=0; i<32; i++)
+        if (fNodes[i])
+            if (fNodes[i]->IsZombieNode())
+                return true;
+
+    return false;
+}
+
+// --------------------------------------------------------------------------
+//
+// try to reboot all zombie nodes to get them working again. all other
+// nodes are left untouched.
+//
+bool Network::RebootZombies()
+{
+    lout << "- Trying to reboot all Zombies..." << endl;
+    for (int i=0; i<32; i++)
+        if (fNodes[i])
+            if (fNodes[i]->IsZombieNode())
+                if (!fNodes[i]->Reboot())
+                {
+                    lout << "- Failed to reboot " << fNodes[i]->GetNodeName() << "." << endl;
+                    return false;
+                }
+
+    lout << "- All Zombies rebooted." << endl;
+
+    return true;
+}
Index: trunk/MagicSoft/Cosy/candrv/network.h
===================================================================
--- trunk/MagicSoft/Cosy/candrv/network.h	(revision 1701)
+++ trunk/MagicSoft/Cosy/candrv/network.h	(revision 1702)
@@ -32,4 +32,7 @@
 
     bool HasError() const;
+    bool HasZombie() const;
+
+    bool RebootZombies();
 
     ClassDef(Network, 0) // collection of nodes (nodedrv)
Index: trunk/MagicSoft/Cosy/candrv/nodedrv.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/nodedrv.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/candrv/nodedrv.cc	(revision 1702)
@@ -87,4 +87,15 @@
 // --------------------------------------------------------------------------
 //
+// This should be called from a master or main thread to get a node out
+// of the Zombie-Status. Overload it by your needs.
+//
+bool NodeDrv::Reboot()
+{
+    fIsZombie = false;
+    return true;
+}
+
+// --------------------------------------------------------------------------
+//
 // Init device, sets the pointer to the whole network and enables
 // the Can messages to be passed through the interface:
@@ -315,5 +326,10 @@
 bool NodeDrv::WaitForSdo(WORD_t idx, BYTE_t subidx, WORDS_t timeout)
 {
-    return fNetwork->WaitForSdo(fId, idx, subidx, timeout);
+    bool rc = fNetwork->WaitForSdo(fId, idx, subidx, timeout);
+
+    if (!rc)
+        fIsZombie = kTRUE;
+
+    return rc;
 }
 
Index: trunk/MagicSoft/Cosy/candrv/nodedrv.h
===================================================================
--- trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 1701)
+++ trunk/MagicSoft/Cosy/candrv/nodedrv.h	(revision 1702)
@@ -34,5 +34,5 @@
     void DelError()        { fError = 0; }
 
-    Bool_t fIsZombie;
+    Bool_t fIsZombie; // A Zombie node is a node which doesn't answer...
 
 public:
@@ -60,4 +60,6 @@
     virtual void HandlePDO3(BYTE_t *data, timeval_t *tv) {};
     virtual void HandlePDO4(BYTE_t *data, timeval_t *tv) {};
+
+    virtual bool Reboot();
 
     void SendPDO1(BYTE_t data[8]);
Index: trunk/MagicSoft/Cosy/candrv/vmodican.cc
===================================================================
--- trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/candrv/vmodican.cc	(revision 1702)
@@ -202,5 +202,5 @@
     const WORD_t cobid = desc>>5;
 
-    switch (msg->cmd)
+    switch (msg->cmd) // FROM mican.h
     {
     case M_MSG_LOST:
@@ -208,6 +208,14 @@
         return;
 
+    case M_BCAN_TX_con:  /* confirm (+/-) transmission */
+        cout << "VmodIcan reports: CTXcon=0x35" << endl;
+        cout << "This normally means, that the transmission of the following CAN frame failed:" << hex << endl;
+        cout << "Descr: 0x" << cobid << dec;
+        cout << "  Rtr: "   << (rtr?"Yes":"No");
+        cout << "  Len: "   << (int)len << endl;
+        return;
+
     case M_BCAN_EVENT_ind:
-        cout << "VmodIcan reports: CEVTind=0x37, " << hex;
+        cout << "VmodIcan reports: CEVTind=0x37: " << hex;
         switch (msg->data[0]) // error indicator
         {
Index: trunk/MagicSoft/Cosy/cosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/cosy.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/cosy.cc	(revision 1702)
@@ -50,5 +50,5 @@
     // check for the right usage of the program
     //
-    int mode = 2;
+    int mode = 0;
     if (argc==2 && (argv[1][0]=='-' || argv[1][1]=='m'))
         switch (argv[1][2])
@@ -59,4 +59,7 @@
         case '1':      // SE mode
             mode = 1;
+            break;
+        case '2':      // GUI demo mode
+            mode = 2;
             break;
         }
Index: trunk/MagicSoft/Cosy/devdrv/macs.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 1702)
@@ -243,10 +243,12 @@
     WaitForSdo(0x2004);
     */
-    EnableTimeout(kFALSE);
-
     lout << "- " << GetNodeName() << ": Requesting Mac Software Version." << endl;
     RequestSDO(0x100a);
     WaitForSdo(0x100a);
 
+    if (IsZombie())
+        return;
+
+    EnableTimeout(kFALSE);
     SetRpmMode(FALSE);
 
@@ -437,6 +439,14 @@
     fPdoPos    = (data[4]<<24) | (data[5]<<16) | (data[6]<<8) | data[7];
 
-    fPosActive = data[3]&0x02;
-    fRpmActive = data[3]&0x04;
+              // data[3]&0x01; // motor not moving
+    fPosActive = data[3]&kPosActive; // positioning active
+    fRpmActive = data[3]&kRpmActive; // RPM mode switched on
+              // data[3]&0x08; //  - unused -
+              // data[3]&0x10; //  - unused -
+              // data[3]&0x20; //  - unused -
+    fInControl = data[3]&0x40; // motor uncontrolled
+              // data[3]&0x80; // axis resetted (after errclr, motor stop, motor on)
+
+    fStatus = data[3];
 
     fPdoTime.SetTimer(tv);
@@ -450,5 +460,5 @@
     //
     // errnum==0 gives a sudden information that something happened. Now the
-    // microcontroller is running inside its interrup procedure which
+    // microcontroller is running inside its interrupt procedure which
     // stopped the normal program. The interrupt procedure should try to clear
     // the error state of the hardware. This should never create a new error!
Index: trunk/MagicSoft/Cosy/devdrv/macs.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 1701)
+++ trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 1702)
@@ -25,4 +25,6 @@
     BYTE_t   fPosActive;
     BYTE_t   fRpmActive;
+    BYTE_t   fInControl;
+    BYTE_t   fStatus;
 
     TTimer  *fTimeout;
@@ -40,4 +42,14 @@
 
 public:
+    enum
+    {
+        kNotMoving = BIT(0),    // motor not moving
+        kPosActive = BIT(1),    // positioning active
+        kRpmActive = BIT(2),    // RPM mode switched on
+        // BIT(3-5) unsused
+        kOutOfControl = BIT(6), // motor uncontrolled
+        kAxisReset = BIT(7)     // axis resetted (after errclr, motor stop, motor on)
+    };
+
     Macs(const BYTE_t nodeid, const char *name=NULL, MLog &out=gLog);
     virtual ~Macs();
@@ -90,5 +102,6 @@
     void StopMotor();
 
-    int IsPositioning() { return fPosActive; }
+    int IsPositioning() const { return fPosActive; }
+    BYTE_t GetStatus() const { return fStatus; }
 
     double GetTime();
@@ -98,10 +111,10 @@
     double GetPdoMjd();
 
-    LWORDS_t GetPdoPos() { return fPdoPos; }
+    LWORDS_t GetPdoPos() const { return fPdoPos; }
 
-    LWORDS_t GetPos()    { return fPos; }
-    LWORDS_t GetVel()    { return fVel; }
-    LWORD_t  GetVelRes() { return fVelRes; } // Velocity units (would be 100 for %)
-    LWORD_t  GetRes()    { return fRes; }    // Encoder resolution
+    LWORDS_t GetPos()    const { return fPos; }
+    LWORDS_t GetVel()    const { return fVel; }
+    LWORD_t  GetVelRes() const { return fVelRes; } // Velocity units (would be 100 for %)
+    LWORD_t  GetRes()    const { return fRes; }    // Encoder resolution
 
     void HandleError();
Index: trunk/MagicSoft/Cosy/gui/MGAccuracy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/gui/MGAccuracy.cc	(revision 1702)
@@ -178,4 +178,6 @@
 
     InitCanvas();
+
+    SetNoContextMenu();
 }
 
Index: trunk/MagicSoft/Cosy/gui/MGCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.cc	(revision 1702)
@@ -238,11 +238,15 @@
     fList->Add(fAzSoll);
 
-
-    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     = new TGLabel(f, "Error");
+    fMoving    = new TGLabel(f, "Moving");
+    fTracking  = new TGLabel(f, "Tracking");
+    fStopping  = new TGLabel(f, "Stopping");
+    fStopped   = new TGLabel(f, "Stopped");
+    fAvailMac1 = new TGLabel(f, "- MAC1 -");
+    fAvailMac2 = new TGLabel(f, "- MAC2 -");
+    fAvailMac3 = new TGLabel(f, "- MAC3 -");
+    fAvailSe1  = new TGLabel(f, "-SE/Zd1-");
+    fAvailSe2  = new TGLabel(f, "-SE/Zd2-");
+    fAvailSe3  = new TGLabel(f, "- SE/Az -");
 
     ULong_t color;
@@ -250,4 +254,10 @@
     gClient->GetColorByName("Red", color);
     fError->SetBackgroundColor(color);
+    fAvailMac1->SetBackgroundColor(color);
+    fAvailMac2->SetBackgroundColor(color);
+    fAvailMac3->SetBackgroundColor(color);
+    fAvailSe1->SetBackgroundColor(color);
+    fAvailSe2->SetBackgroundColor(color);
+    fAvailSe3->SetBackgroundColor(color);
     gClient->GetColorByName("LightBlue", color);
     fMoving->SetBackgroundColor(color);
@@ -264,4 +274,10 @@
     fStopping->Move(10, 25+60);
     fStopped ->Move(10, 25+80);
+    fAvailMac1->Move(10, 25+120);
+    fAvailMac2->Move(10, 25+140);
+    fAvailMac3->Move(10, 25+160);
+    fAvailSe1->Move(10, 25+180);
+    fAvailSe2->Move(10, 25+200);
+    fAvailSe3->Move(10, 25+220);
 
     fError   ->Resize(60, 20);
@@ -270,4 +286,10 @@
     fStopping->Resize(60, 20);
     fStopped ->Resize(60, 20);
+    fAvailMac1->Resize(60, 20);
+    fAvailMac2->Resize(60, 20);
+    fAvailMac3->Resize(60, 20);
+    fAvailSe1->Resize(60, 20);
+    fAvailSe2->Resize(60, 20);
+    fAvailSe3->Resize(60, 20);
 
     fList->Add(fError);
@@ -276,4 +298,10 @@
     fList->Add(fStopping);
     fList->Add(fStopped);
+    fList->Add(fAvailMac1);
+    fList->Add(fAvailMac2);
+    fList->Add(fAvailMac3);
+    fList->Add(fAvailSe1);
+    fList->Add(fAvailSe2);
+    fList->Add(fAvailSe3);
 }
 
@@ -679,4 +707,25 @@
     cout << "MGCosy::~MGCosy done." << endl;
 }
+
+void MGCosy::SetLabelColor(TGLabel *label, Bool_t col)
+{
+    ULong_t red, green;
+
+    gClient->GetColorByName("Red",   red);
+    gClient->GetColorByName("Green", green);
+
+    if (col && label->TestBit(BIT(14)))
+        return;
+
+    if (!col && !label->TestBit(BIT(14)))
+        return;
+
+    col ? label->SetBit(BIT(14)) : label->ResetBit(BIT(14));
+
+    label->UnmapWindow();
+    label->SetBackgroundColor(col ? green : red);
+    label->MapWindow();
+}
+
 // ======================================================================
 void MGCosy::EnableLabel(TGLabel *label, Bool_t stat)
@@ -823,5 +872,5 @@
 
 void MGCosy::Update(ZdAz pos, ZdAz acc, ZdAz vel, ZdAz off, RaDec radec,
-                    ZdAz soll, UInt_t stat)
+                    ZdAz soll, UInt_t stat, UInt_t stat2)
 {
     double mjd = UpdateTime();
@@ -848,4 +897,11 @@
     EnableLabel(fZdSoll,   stat&kMoving);
     EnableLabel(fAzSoll,   stat&kMoving);
+
+    SetLabelColor(fAvailMac1, stat2&0x01);
+    SetLabelColor(fAvailMac2, stat2&0x02);
+    SetLabelColor(fAvailMac3, stat2&0x04);
+    SetLabelColor(fAvailSe1,  stat2&0x08);
+    SetLabelColor(fAvailSe2,  stat2&0x10);
+    SetLabelColor(fAvailSe3,  stat2&0x20);
 
     stat&kTracking ? fAccuracy->MapWindow() : fAccuracy->UnmapWindow();
Index: trunk/MagicSoft/Cosy/gui/MGCosy.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 1701)
+++ trunk/MagicSoft/Cosy/gui/MGCosy.h	(revision 1702)
@@ -77,4 +77,10 @@
     TGLabel *fStopping;
     TGLabel *fStopped;
+    TGLabel *fAvailMac1;
+    TGLabel *fAvailMac2;
+    TGLabel *fAvailMac3;
+    TGLabel *fAvailSe1;
+    TGLabel *fAvailSe2;
+    TGLabel *fAvailSe3;
 
     TGListBox *fLog;
@@ -91,4 +97,5 @@
 
     void EnableLabel(TGLabel *label, Bool_t stat);
+    void SetLabelColor(TGLabel *label, Bool_t col);
     void UpdateOffset(ZdAz &off);
     void UpdateZdAz(ZdAz &off);
@@ -108,5 +115,5 @@
     TGListBox *GetLog() const { return fLog; }
 
-    void Update(ZdAz pos, ZdAz acc, ZdAz vel, ZdAz off, RaDec radec, ZdAz soll, UInt_t stat);
+    void Update(ZdAz pos, ZdAz acc, ZdAz vel, ZdAz off, RaDec radec, ZdAz soll, UInt_t stat, UInt_t stat2);
 
     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 1701)
+++ trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.cc	(revision 1702)
@@ -52,4 +52,9 @@
 }
 
+// ------------------------------------------------------------------------
+//
+// Map the subwindows, resize to its quadratic size, map the window itself
+// and set it to Non-Editable.
+//
 void MGEmbeddedCanvas::InitCanvas()
 {
@@ -71,5 +76,5 @@
     // X11 Pixmap error) Update hangs the Gui system.
     //
-    // Fixed: Using root 3.01/06 and doing the update from within the
+    // Fixed: By using root 3.01/06 and doing the update from within the
     // mainthread.
     //
@@ -80,2 +85,15 @@
     fModified = kFALSE;
 }
+
+// ------------------------------------------------------------------------
+//
+//  Set's the kNoContextMenu bit for all primitives in the embedded canvas
+//  and the canvas itself, so that no context menu is displayed.
+//
+void MGEmbeddedCanvas::SetNoContextMenu()
+{
+    TList &list = *fCanvas->GetListOfPrimitives();
+    list.ForEach(TObject, SetBit)(kNoContextMenu);
+
+    fCanvas->SetBit(kNoContextMenu);
+}
Index: trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.h
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.h	(revision 1701)
+++ trunk/MagicSoft/Cosy/gui/MGEmbeddedCanvas.h	(revision 1702)
@@ -41,4 +41,6 @@
     void SetModified() { fModified = kTRUE; }
 
+    void SetNoContextMenu();
+
     ClassDef(MGEmbeddedCanvas, 0)
 };
Index: trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/gui/MGSkyPosition.cc	(revision 1702)
@@ -177,4 +177,5 @@
     InitText();
     InitCanvas();
+    SetNoContextMenu();
 }
 
Index: trunk/MagicSoft/Cosy/gui/MGVelocity.cc
===================================================================
--- trunk/MagicSoft/Cosy/gui/MGVelocity.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/gui/MGVelocity.cc	(revision 1702)
@@ -188,4 +188,6 @@
 
     InitCanvas();
+
+    SetNoContextMenu();
 }
 
Index: trunk/MagicSoft/Cosy/main/MCosy.cc
===================================================================
--- trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 1701)
+++ trunk/MagicSoft/Cosy/main/MCosy.cc	(revision 1702)
@@ -150,7 +150,7 @@
     // Get the values
     //
-    const int p0 = fZd1 ? fZd1->GetPos() : 0;
-    const int p1 = fZd2 ? fZd2->GetPos() : 0;
-    const int p2 = fAz  ? fAz->GetPos()  : 0;
+    const int p0 = !fZd1->IsZombieNode() ? fZd1->GetPos() : 0;
+    const int p1 = !fZd2->IsZombieNode() ? fZd2->GetPos() : 0;
+    const int p2 = !fAz->IsZombieNode()  ? fAz->GetPos()  : 0;
 
     const int a0 = p0; //p0>8192?p0-16384:p0;
@@ -177,5 +177,5 @@
 Bool_t MCosy::RequestRePos()
 {
-    if (!(fMac1 && fMac2))
+    if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
         return kTRUE;
 
@@ -192,5 +192,5 @@
 
     //
-    // If waitng was not interrupted everything is ok. return.
+    // If waiting was not interrupted everything is ok. return.
     //
     if (!StopWaitingForSDO())
@@ -216,5 +216,5 @@
 ZdAz MCosy::GetRePos()
 {
-    return fMac1 && fMac2 ? ZdAz(fMac2->GetPos(), fMac1->GetPos()) : ZdAz(0,0);
+    return !fMac1->IsZombieNode() && !fMac2->IsZombieNode() ? ZdAz(fMac2->GetPos(), fMac1->GetPos()) : ZdAz(0,0);
 }
 
@@ -304,5 +304,5 @@
 int MCosy::StopWaitingForSDO() const
 {
-    return Break() || HasError();
+    return Break() || HasError() || HasZombie();
 }
 
@@ -346,5 +346,5 @@
 
     //
-    // No try to handle the error.
+    // Now try to handle the error.
     //
     fMac1->HandleError();
@@ -378,7 +378,7 @@
     // FIXME: Correct by fOffset ?
 
-    if (!(fMac1 && fMac2))
+    if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
     {
-        cout << "SetPosition: No MACS!" << endl;
+        cout << "SetPosition: No connection to at least one of the MACS!" << endl;
         return TRUE;
     }
@@ -515,5 +515,5 @@
 void MCosy::InitTracking()
 {
-    if (!(fMac1 && fMac2))
+    if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
         return;
 
@@ -656,5 +656,5 @@
     fRaDec = dst;
 
-    if (!(fMac1 && fMac2))
+    if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
         return;
 
@@ -774,6 +774,7 @@
 void MCosy::StopMovement()
 {
-    if (!fMac1 || !fMac2)
+    if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
         return;
+
     //
     // Set status to Stopping
@@ -810,4 +811,12 @@
 void *MCosy::Proc(int msg, void *mp)
 {
+    lout << "Checking for Zombies" << endl;
+    if (HasZombie())
+    {
+        lout << "Found Zombies" << endl;
+        if (!RebootZombies())
+            return (void*)0xebb0;
+    }
+
     switch (msg)
     {
@@ -823,7 +832,7 @@
     case WM_PRESET:
         cout << "WM_Preset: start." << endl;
-        if (fZd1) fZd1->SetPreset();
-        if (fZd2) fZd2->SetPreset();
-        if (fAz)  fAz->SetPreset();
+        if (!fZd1->IsZombieNode()) fZd1->SetPreset();
+        if (!fZd2->IsZombieNode()) fZd2->SetPreset();
+        if (!fAz->IsZombieNode())  fAz->SetPreset();
         cout << "WM_Preset: done. (return 0xaffe)" << endl;
         return (void*)0xaffe;
@@ -849,9 +858,9 @@
             cout << "Got  Zd: " << sepos.Zd() << " Az: " << sepos.Az() << endl;
 
-            if (fZd1)
+            if (!fZd1->IsZombieNode())
                 fZd1->SetPreset(za.Zd());
-            if(fZd2)
+            if (!fZd2->IsZombieNode())
                 fZd2->SetPreset(-za.Zd());
-            if(fAz)
+            if (!fAz->IsZombieNode())
                 fAz->SetPreset(za.Az());
 
@@ -924,9 +933,10 @@
     case WM_HOME:
         cout << "WM_Home: START" << endl;
-        if (fMac1 && fMac2)
+        if (!fMac1->IsZombieNode() && !fMac2->IsZombieNode())
         {
             cout << "Going Home..." << endl;
-            fMac1->SetHome(250000, 100);
-            fMac2->SetHome(250000, 100);
+            TEnv env(".cosyrc");
+            fMac1->SetHome(250000, env.GetValue("Az_MaxTime2ReachHome[s]", 100));
+            fMac2->SetHome(250000, env.GetValue("Zd_MaxTime2ReachHome[s]", 100));
 
             fAz->SetPreset();
@@ -991,8 +1001,8 @@
 
     Double_t resreaz = 0;
-    if (fMac1)
+    if (!fMac1->IsZombieNode())
         resreaz = fMac1->GetRes();
     else
-        if (fMac3)
+        if (!fMac3->IsZombieNode())
             resreaz = fMac3->GetRes();
         else
@@ -1000,5 +1010,5 @@
 
     Double_t resrezd = 0;
-    if (fMac2)
+    if (!fMac2->IsZombieNode())
         resrezd = fMac2->GetRes();
     else
@@ -1006,8 +1016,8 @@
  
     Double_t ressezd = 0;
-    if (fZd1)
+    if (!fZd1->IsZombieNode())
         ressezd = fZd1->GetPhysRes();
     else
-        if (fZd2)
+        if (!fZd2->IsZombieNode())
             ressezd = fZd2->GetPhysRes();
         else
@@ -1015,5 +1025,5 @@
 
     Double_t resseaz = 0;
-    if (fAz)
+    if (!fAz->IsZombieNode())
         resseaz = fAz->GetPhysRes();
     else
@@ -1024,13 +1034,13 @@
     cout << "done." << endl;
 
-    cout << "Setting Gear Ratios:" << endl;
-    cout << "--------------------" << endl;
-    cout << " X: " << gzd << "*" << resrezd << "/" << ressezd << "=" << kGearRatio.X() << endl;
-    cout << " Y: " << gaz << "*" << resreaz << "/" << resseaz << "=" << kGearRatio.Y() << endl;
+    cout << " * Setting Gear Ratios:" << endl;
+    cout << "   --------------------" << endl;
+    cout << " *  X: " << gzd << "*" << resrezd << "/" << ressezd << "=" << kGearRatio.X() << endl;
+    cout << " *  Y: " << gaz << "*" << resreaz << "/" << resseaz << "=" << kGearRatio.Y() << endl;
 }
 
 void MCosy::TalkThread()
 {
-    if (!(fMac1 && fMac2))
+    if (fMac1->IsZombieNode() || fMac2->IsZombieNode())
         return;
 
@@ -1048,8 +1058,5 @@
     }
 
-    //fMac1->EnableTimeout(kTRUE, 500);
-    //fMac2->EnableTimeout(kTRUE, 500);
-
-    if (!(fZd1 && fZd2 && fAz))
+    if (fZd1->IsZombieNode() || fZd2->IsZombieNode() || fAz->IsZombieNode())
         return;
 
@@ -1058,7 +1065,7 @@
     // Start the Network
     //
-    cout << "Reading configuration file..." << flush;
-    TEnv env(".cosyrc");
-    cout << "done." << endl;
+    //cout << "Reading configuration file..." << flush;
+    //TEnv env(".cosyrc");
+    //cout << "done." << endl;
 /*
     const int res = fMac3->GetVelRes();
@@ -1067,10 +1074,4 @@
     fMac3->SetAcceleration(res);
     fMac3->SetDeceleration(res);
-
-    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();
@@ -1098,36 +1099,7 @@
     fMac2->EnableTimeout(kTRUE, 500);
 
-    const Double_t gaz = env.GetValue("Az_GearRatio[U_mot/U_tel]");
-    const Double_t gzd = env.GetValue("Zd_GearRatio[U_mot/U_tel]");
-
-    const Double_t resreaz = env.GetValue("Az_ResRE[re/U_mot]");
-    const Double_t resrezd = env.GetValue("Zd_ResRE[re/U_mot]");
-
-    kGearRatio.Set (gzd*resrezd/RES_SE, gaz*resreaz/RES_SE);   //[re/se]
-    kGearRatio2.Set(gzd*resrezd/360.0,  gaz*resreaz/360.0);    //[re/deg]
-
     //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;
@@ -1255,14 +1227,28 @@
     // Update Gui, foremer MTGui.
     //
-    if (fZd1) fZd1->DisplayVal();
-    if (fZd2) fZd2->DisplayVal();
-    if (fAz)  fAz->DisplayVal();
+    if (!fZd1->IsZombieNode()) fZd1->DisplayVal();
+    if (!fZd2->IsZombieNode()) fZd2->DisplayVal();
+    if (!fAz->IsZombieNode())  fAz->DisplayVal();
 
     ZdAz seist = GetSePos()*2*TMath::Pi()/16384; // [se]
     ZdAz bendist = fBending.CorrectBack(seist);
 
+    Byte_t avail = 0;
+
+    avail |= !fMac1->IsZombieNode() ? 0x01 : 0;
+    avail |= !fMac2->IsZombieNode() ? 0x02 : 0;
+    avail |= !fMac3->IsZombieNode() ? 0x04 : 0;
+    avail |= !fZd1->IsZombieNode()  ? 0x08 : 0;
+    avail |= !fZd2->IsZombieNode()  ? 0x10 : 0;
+    avail |= !fAz->IsZombieNode()   ? 0x20 : 0;
+
     fWin->Update(bendist*(360.0/2/TMath::Pi()), fTrackingError/kGearRatio2,
-                 fVelocity, fOffset/*/kGearRatio2*/, fRaDec, fZdAzSoll,
-                 fStatus);
+                 fVelocity, fOffset, fRaDec, fZdAzSoll, fStatus, avail);
+
+    /*
+     cout << (int)(fMac1->GetStatus()&Macs::kOutOfControl) << " ";
+     cout << (int)(fMac2->GetStatus()&Macs::kOutOfControl) << " ";
+     cout << (int)(fMac3->GetStatus()&Macs::kOutOfControl) << endl;
+     */
 
     return kTRUE;
@@ -1282,5 +1268,5 @@
     // Don't call this function twice!
     Network::Start();
-
+/*
     if (fMac1)
         if (fMac1->IsZombieNode()) { delete fMac1; fMac1=NULL; }
@@ -1289,16 +1275,16 @@
     if (fMac3)
         if (fMac3->IsZombieNode()) { delete fMac3; fMac3=NULL; }
-
-    if (fZd1)
+*/
+/*    if (fZd1)
         if (fZd1->IsZombieNode())  { delete fZd1;  fZd1=NULL; }
-        else fZd1->SetDisplay(fWin->GetLabel2());
-
-    if (fZd2)
+        else */fZd1->SetDisplay(fWin->GetLabel2());
+
+/*    if (fZd2)
         if (fZd2->IsZombieNode())  { delete fZd2;  fZd2=NULL; }
-        else fZd2->SetDisplay(fWin->GetLabel3());
-
-    if (fAz)
+        else */fZd2->SetDisplay(fWin->GetLabel3());
+
+/*    if (fAz)
         if (fAz->IsZombieNode())   { delete fAz;   fAz=NULL; }
-        else fAz->SetDisplay(fWin->GetLabel1());
+        else */fAz->SetDisplay(fWin->GetLabel1());
 
     ReadConfig();
@@ -1345,6 +1331,6 @@
     lout << "- Setting up network." << endl;
 
-    fMac1=new Macs(id1, "Mac/Az",      lout);
-    fMac2=new Macs(id3, "Mac/Zd",      lout);
+    fMac1=new Macs(id1, "Mac/Az", lout);
+    fMac2=new Macs(id3, "Mac/Zd", lout);
     if (id2>=0)
         fMac3=new Macs(id2, "Mac/Az-Sync", lout);
