Index: trunk/MagicSoft/Cosy/devdrv/macs.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 4076)
+++ trunk/MagicSoft/Cosy/devdrv/macs.cc	(revision 4104)
@@ -382,5 +382,5 @@
     //SetNoWait(TRUE);
 
-    StartGuarding(400, 1, kFALSE); // Using PDO1 @ 100ms
+    //StartGuarding(400, 1, kFALSE); // Using PDO1 @ 100ms
     //StartGuarding(250, 4);
     //StartHostGuarding();
Index: trunk/MagicSoft/Cosy/devdrv/macs.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 4076)
+++ trunk/MagicSoft/Cosy/devdrv/macs.h	(revision 4104)
@@ -1,7 +1,12 @@
-#ifndef MACS_H
-#define MACS_H
+#ifndef COSY_Macs
+#define COSY_Macs
 
+#ifndef COSY_NodeDrv
 #include "nodedrv.h"
+#endif
+
+#ifndef MARS_MTime
 #include "MTime.h"
+#endif
 
 class Macs : public NodeDrv
@@ -119,4 +124,6 @@
 
     Double_t GetPosTime() const { return fPosTime; }
+    Double_t GetMjd() const { return fPosTime.GetMjd(); }
+    Double_t GetPdoMjd() const { return fPdoTime.GetMjd(); }
 
     ClassDef(Macs, 0)
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 4076)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.cc	(revision 4104)
@@ -8,4 +8,6 @@
 #include <TGLabel.h>       // TGLabel->SetText
 
+#include "macs.h"
+
 ClassImp(ShaftEncoder);
 
@@ -14,8 +16,20 @@
 ShaftEncoder::ShaftEncoder(const BYTE_t nodeid, const char *name, MLog &out)
     : NodeDrv(nodeid, name, out), fPos(0), fVel(0), fAcc(0),
-    fTurn(0), fLabel(NULL), fPosHasChanged(false), fReport(NULL)
-{
-}
-
+    fTurn(0), fLabel(NULL), fPosHasChanged(false), fReport(NULL),/*fTwin(0),
+    fIsUpdated(kFALSE),*/ fMotor(0), fOffset(0)
+{
+}
+/*
+void ShaftEncoder::CheckTwin(Int_t diff) const
+{
+    if (!fTwin)
+        return;
+
+    if (fTwin->fIsUpdated)
+        fTwin->fIsUpdated = kFALSE;
+    else
+        fTwin->fOffset += diff;
+}
+*/
 void ShaftEncoder::HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv)
 {
@@ -79,4 +93,7 @@
         fPos  = val;
         fTurn = 0;
+        fOffset = fMotor ? fMotor->GetPdoPos() : 0;
+        //fIsUpdated=kTRUE;
+        //fOffset = 0;
         return;
 
@@ -154,18 +171,18 @@
 void ShaftEncoder::DisplayVal()
 {
+    const LWORDS_t pos = GetPos();
     if (IsZombieNode())
     {
         fLabel->SetText(new TGString(""));
-        fUpdPos = ~fPos;
+        fUpdPos = ~pos;
         return;
     }
 
     char text[21];
-
-    if (fPos!=fUpdPos && fLabel)
-    {
-        sprintf(text, "%ld", fPos);
+    if (pos!=fUpdPos && fLabel)
+    {
+        sprintf(text, "%ld", pos);
         fLabel->SetText(new TGString(text));
-        fUpdPos = fPos;
+        fUpdPos = pos;
     }
 }
@@ -177,16 +194,21 @@
     //
     LWORDS_t pos = data[0] | (data[1]<<8) | (data[2]<<16); // | (data[3]<<24);
-    if (pos==fPos)
-        return;
+
+    //if (pos==fPos)
+    //    return;
 
     fPos = pos;
+    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
     fTime.Set(*tv);
     fPosHasChanged = true;
 
+    //CheckTwin(fPos-pos);
+    //fIsUpdated=kTRUE;
+
     if (fReport)
     {
-        fReport->Lock();
+        fReport->Lock("ShaftEncoder::HandlePDOType0");
         *fReport << "SE-REPORT " << (int)GetId() << " " << fTime << " PDO0 " << pos << " " << GetNodeName() << endl;
-        fReport->UnLock();
+        fReport->UnLock("ShaftEncoder::HandlePDOType0");
     }
 }
@@ -200,10 +222,14 @@
     BYTE_t   flag = data[4];
 
-    if (fPos==pos)
-        return;
-
+    //if (fPos==pos)
+    //    return;
+
+    //CheckTwin(fPos-pos);
     fPos=pos;
+    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
     fTime.Set(*tv);
     fPosHasChanged=true;
+    //fIsUpdated=kTRUE;
+    //fOffset = 0;
 
     flag=flag;
@@ -211,7 +237,7 @@
     if (fReport)
     {
-        fReport->Lock();
+        fReport->Lock("ShaftEncoder::HandlePDOType1");
         *fReport << "SE-REPORT " << (int)GetId() << " " << fTime << " PDO1 " << pos << " " << (int)flag << " " << GetNodeName() << endl;
-        fReport->UnLock();
+        fReport->UnLock("ShaftEncoder::HandlePDOType1");
     }
 }
@@ -241,18 +267,24 @@
         turn--;
 
-    if (fPos==pos && fTurn==fTurn)
-        return;
+    //if (fPos==pos && fTurn==fTurn)
+    //    return;
+
+    //CheckTwin(fPos-pos);
 
     fPos  = pos;
     fTurn = turn;
 
+    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
     fTime.Set(*tv);
     fPosHasChanged=true;
+    //fIsUpdated=kTRUE;
+    //fOffset = 0;
+
 
     if (fReport)
     {
-        fReport->Lock();
+        fReport->Lock("ShaftEncoder::HandlePDOType2");
         *fReport << "SE-REPORT " << (int)GetId() << " " << fTime << " PDO2 " << pos << " " << fVel << " " << fAcc << " " << GetNodeName() << endl;
-        fReport->UnLock();
+        fReport->UnLock("ShaftEncoder::HandlePDOType2");
     }
 }
@@ -383,4 +415,6 @@
     fPos  = pre%16384;
     fTurn = pre/16384;
+
+    fOffset = fMotor ? fMotor->GetPdoPos() : 0;
 }
 
Index: trunk/MagicSoft/Cosy/devdrv/shaftencoder.h
===================================================================
--- trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 4076)
+++ trunk/MagicSoft/Cosy/devdrv/shaftencoder.h	(revision 4104)
@@ -1,8 +1,14 @@
-#ifndef SHAFTENCODER_H
-#define SHAFTENCODER_H
+#ifndef COSY_ShafTEncoder
+#define COSY_ShafTEncoder
 
+#ifndef COSY_NodeDrv
 #include "nodedrv.h"
+#endif
+
+#ifndef MARS_MTime
 #include "MTime.h"
+#endif
 
+class Macs;
 class TGLabel;
 
@@ -19,6 +25,4 @@
     TGLabel  *fLabel;     //
     LWORDS_t  fUpdPos;    // ticks
-    //    WORDS_t   fUpdVel;    // ticks per 5ms
-    //    WORDS_t   fUpdAcc;    // ticks per 25ms^2
 
     bool fPosHasChanged;  //!
@@ -26,4 +30,7 @@
     MTime fTime;
     MLog *fReport;
+
+    Macs *fMotor;
+    Int_t fOffset;
 
     void HandlePDOType0(BYTE_t *data, timeval_t *tv);
@@ -35,4 +42,5 @@
     void Init();
     void CheckConnection();
+    // void CheckTwin(Int_t diff) const;
 
 public:
@@ -42,4 +50,6 @@
 
     void SetDisplay(TGLabel *label) { fLabel = label; }
+    void SetMotor(Macs *m) { fMotor = m; }
+    //void SetTwin(ShaftEncoder *se) { fTwin = se; }
 
     void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv);
@@ -52,6 +62,8 @@
     void HandlePDO2(BYTE_t *data, timeval_t *tv) { HandlePDOType2(data, tv); }
 
-    LWORDS_t GetPos() { return IsZombieNode() ? 0 : fPos+fTurn*fTicks; } // FIXME? 0?
-    LWORD_t  GetPhysRes() { return fTicks; }
+    LWORDS_t GetPos() const { return IsZombieNode() ? 0 : fPos+fTurn*fTicks; } // FIXME? 0?
+    LWORD_t  GetPhysRes() const { return fTicks; }
+    Int_t    GetOffset() const { return fOffset; }
+    void     SetOffset(Int_t off) { fOffset = off; }
 
     double GetMjd();
