Merged
authorLaurent Bessard
Tue, 30 Apr 2013 01:31:47 +0200
changeset 2141 6963460bfe0f
parent 2140 56643934495c (diff)
parent 2135 ca1c34ff6c10 (current diff)
child 2142 f407a0e154c5
Merged
etherlab/EthercatMaster.py
--- a/etherlab/ConfigEditor.py	Fri Apr 26 13:59:43 2013 +0200
+++ b/etherlab/ConfigEditor.py	Tue Apr 30 01:31:47 2013 +0200
@@ -984,10 +984,6 @@
                 maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
         event.Skip()
     
-def GetModulesTableColnames():
-    _ = lambda x : x
-    return [_("Name"), _("PDO alignment (bits)")]
-
 class LibraryEditorSizer(wx.FlexGridSizer):
     
     def __init__(self, parent, module_library, buttons):
@@ -1046,16 +1042,30 @@
                     wx.TR_COLUMN_LINES |
                     wx.TR_HIDE_ROOT |
                     wx.TR_FULL_ROW_HIGHLIGHT)
-        self.ModulesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DCLICK,
-            self.OnModulesGridLeftDClick)
+        self.ModulesGrid.GetMainWindow().Bind(wx.EVT_LEFT_DOWN,
+            self.OnModulesGridLeftDown)
+        self.ModulesGrid.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT,
+            self.OnModulesGridBeginLabelEdit)
+        self.ModulesGrid.Bind(wx.EVT_TREE_END_LABEL_EDIT,
+            self.OnModulesGridEndLabelEdit)
+        self.ModulesGrid.GetHeaderWindow().Bind(wx.EVT_MOTION, 
+            self.OnModulesGridHeaderMotion)
         self.AddWindow(self.ModulesGrid, border=10, 
             flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
         
-        for colname, colsize, colalign in zip(GetModulesTableColnames(),
-                                              [400, 150],
-                                              [wx.ALIGN_LEFT, wx.ALIGN_RIGHT]):
-            self.ModulesGrid.AddColumn(_(colname), colsize, colalign)
+        for colname, colsize, colalign in zip(
+                [_("Name")] + [param_infos["column_label"] 
+                               for param, param_infos in 
+                               self.ModuleLibrary.MODULES_EXTRA_PARAMS],
+                [400] + [param_infos["column_size"] 
+                         for param, param_infos in 
+                         self.ModuleLibrary.MODULES_EXTRA_PARAMS],
+                [wx.ALIGN_LEFT] + [wx.ALIGN_RIGHT] * len(self.ModuleLibrary.MODULES_EXTRA_PARAMS)):
+            self.ModulesGrid.AddColumn(_(colname), colsize, colalign, edit=True)
         self.ModulesGrid.SetMainColumn(0)
+        
+        self.CurrentSelectedCol = None
+        self.LastToolTipCol = None
     
     def GetPath(self):
         return self.ModuleLibrary.GetPath()
@@ -1089,7 +1099,10 @@
                 item = self.ModulesGrid.AppendItem(root, "")
             self.ModulesGrid.SetItemText(item, module["name"], 0)
             if module["infos"] is not None:
-                self.ModulesGrid.SetItemText(item, str(module["infos"]["alignment"]), 1)
+                for param_idx, (param, param_infos) in enumerate(self.ModuleLibrary.MODULES_EXTRA_PARAMS):
+                    self.ModulesGrid.SetItemText(item, 
+                                                 str(module["infos"][param]), 
+                                                 param_idx + 1)
             else:
                 self.ModulesGrid.SetItemBackgroundColour(item, wx.LIGHT_GREY)
             self.ModulesGrid.SetItemPyData(item, module["infos"])
@@ -1143,33 +1156,67 @@
                 wx.CallAfter(self.RefreshView)
         event.Skip()
     
-    def OnModulesGridLeftDClick(self, event):
+    def OnModulesGridLeftDown(self, event):
         item, flags, col = self.ModulesGrid.HitTest(event.GetPosition())
         if item.IsOk():
             entry_infos = self.ModulesGrid.GetItemPyData(item)
-            if entry_infos is not None and col == 1:
-                dialog = wx.TextEntryDialog(self.ParentWindow, 
-                    _("Set PDO alignment (bits):"),
-                    _("%s PDO alignment") % self.ModulesGrid.GetItemText(item), 
-                    str(entry_infos["alignment"]))
+            if entry_infos is not None and col > 0:
+                self.CurrentSelectedCol = col
+            else:
+                self.CurrentSelectedCol = None
+        else:
+            self.CurrentSelectedCol = None
+        event.Skip()
+
+    def OnModulesGridBeginLabelEdit(self, event):
+        item = event.GetItem()
+        if item.IsOk():
+            entry_infos = self.ModulesGrid.GetItemPyData(item)
+            if entry_infos is not None:
+                event.Skip()
+            else:
+                event.Veto()
+        else:
+            event.Veto()
+
+    def OnModulesGridEndLabelEdit(self, event):
+        item = event.GetItem()
+        if item.IsOk() and self.CurrentSelectedCol is not None:
+            entry_infos = self.ModulesGrid.GetItemPyData(item)
+            if entry_infos is not None and self.CurrentSelectedCol > 0:
+                param, param_infos = self.ModuleLibrary.MODULES_EXTRA_PARAMS[self.CurrentSelectedCol - 1]
+                stripped_column_label = param_infos["column_label"].split('(')[0].strip()
+                try:
+                    self.ModuleLibrary.SetModuleExtraParam(
+                        entry_infos["vendor"],
+                        entry_infos["product_code"],
+                        entry_infos["revision_number"],
+                        param,
+                        int(event.GetLabel()))
+                    wx.CallAfter(self.RefreshModulesGrid)
+                    event.Skip()
+                except ValueError:
+                    message = wx.MessageDialog(self, 
+                        _("Module %s must be an integer!") % stripped_column_label, 
+                        _("Error"), wx.OK|wx.ICON_ERROR)
+                    message.ShowModal()
+                    message.Destroy()
+                    event.Veto()
+            else:
+                event.Veto()
+        else:
+            event.Veto()
                 
-                if dialog.ShowModal() == wx.ID_OK:
-                    try:
-                        self.ModuleLibrary.SetAlignment(
-                            entry_infos["vendor"],
-                            entry_infos["product_code"],
-                            entry_infos["revision_number"],
-                            int(dialog.GetValue()))
-                        wx.CallAfter(self.RefreshModulesGrid)
-                    except ValueError:
-                        message = wx.MessageDialog(self, 
-                            _("Module PDO alignment must be an integer!"), 
-                            _("Error"), wx.OK|wx.ICON_ERROR)
-                        message.ShowModal()
-                        message.Destroy()
-                    
-                dialog.Destroy()
-        
+    def OnModulesGridHeaderMotion(self, event):
+        item, flags, col = self.ModulesGrid.HitTest(event.GetPosition())
+        if col != self.LastToolTipCol and self.LastToolTipCol is not None:
+            self.ModulesGrid.SetToolTip(None)
+            self.LastToolTipCol = None
+        if col > 0:
+            self.LastToolTipCol = col
+            param, param_infos = self.ModuleLibrary.MODULES_EXTRA_PARAMS[col - 1]
+            wx.CallAfter(self.ModulesGrid.SetToolTip,
+                         wx.ToolTip(param_infos["description"]))
         event.Skip()
 
 class DatabaseManagementDialog(wx.Dialog):
--- a/etherlab/EthercatCFileGenerator.py	Fri Apr 26 13:59:43 2013 +0200
+++ b/etherlab/EthercatCFileGenerator.py	Tue Apr 30 01:31:47 2013 +0200
@@ -201,7 +201,7 @@
             slave_pos = (slave_alias, alias[slave_alias])
             
             # Extract slave device informations
-            device, alignment = self.Controler.GetModuleInfos(type_infos)
+            device, module_extra_params = self.Controler.GetModuleInfos(type_infos)
             if device is not None:
                 
                 # Extract slaves variables to be mapped
@@ -322,6 +322,11 @@
                                 if slave_variables.get((index, subindex), None) is not None:
                                     pdo_mapping_match["matching"] += 1
                         
+                            if pdo.getFixed() != True:
+                                pdo_mapping_match["matching"] += \
+                                    module_extra_params["max_pdo_size"] - \
+                                    pdo_mapping_match["count"]
+                        
                         elif pdo.getMandatory():
                             selected_pdos.append(pdo_index)
                     
@@ -332,7 +337,9 @@
                         if exclusion_scope[0]["matching"] > 0:
                             selected_pdos.append(exclusion_scope[0]["index"])
                             start_excluding_index = 1
-                        excluded_pdos.extend([pdo["index"] for pdo in exclusion_scope[start_excluding_index:] if PdoAssign or not pdo["assigned"]])
+                        excluded_pdos.extend([pdo["index"] 
+                            for pdo in exclusion_scope[start_excluding_index:] 
+                            if PdoAssign or not pdo["assigned"]])
                     
                     for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
                                           [(pdo, "Outputs") for pdo in device.getRxPdo()]):
@@ -475,7 +482,7 @@
                                 
                                 if len(dynamic_pdos[pdo_type]["pdos"]) > 0:
                                     pdo = dynamic_pdos[pdo_type]["pdos"][0]
-                                else:
+                                elif module_extra_params["add_pdo"]:
                                     while dynamic_pdos[pdo_type]["current_index"] in pdos_index:
                                         dynamic_pdos[pdo_type]["current_index"] += 1
                                     if dynamic_pdos[pdo_type]["current_index"] >= dynamic_pdos[pdo_type]["max_index"]:
@@ -493,14 +500,16 @@
                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
                                     dynamic_pdos[pdo_type]["pdos"].append(pdo)
+                                else:
+                                    break
                                 
                                 pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
-                                if entry_infos["bitlen"] < alignment:
-                                    print (alignment, entry_infos["bitlen"])
-                                    pdo["entries"].append("    {0x0000, 0x00, %d}, /* None */" % (alignment - entry_infos["bitlen"]))
+                                if entry_infos["bitlen"] < module_extra_params["pdo_alignment"]:
+                                    pdo["entries"].append("    {0x0000, 0x00, %d}, /* None */" % (
+                                            module_extra_params["pdo_alignment"] - entry_infos["bitlen"]))
                                 pdo["entries_number"] += 1
                                 
-                                if pdo["entries_number"] == 255:
+                                if pdo["entries_number"] == module_extra_params["max_pdo_size"]:
                                     dynamic_pdos[pdo_type]["pdos"].pop(0)
                     
                     pdo_offset = 0
--- a/etherlab/EthercatCIA402Slave.py	Fri Apr 26 13:59:43 2013 +0200
+++ b/etherlab/EthercatCIA402Slave.py	Tue Apr 30 01:31:47 2013 +0200
@@ -11,11 +11,14 @@
 NODE_VARIABLES = [
     ("ControlWord", 0x6040, 0x00, "UINT", "Q"),
     ("TargetPosition", 0x607a, 0x00, "DINT", "Q"),
+    ("TargetVelocity", 0x60ff, 0x00, "DINT", "Q"),
+    ("TargetTorque", 0x6071, 0x00, "INT", "Q"),
     ("ModesOfOperation", 0x06060, 0x00, "SINT", "Q"),
     ("StatusWord", 0x6041, 0x00, "UINT", "I"),
     ("ModesOfOperationDisplay", 0x06061, 0x00, "SINT", "I"),
     ("ActualPosition", 0x6064, 0x00, "DINT", "I"),
-    ("ActualVelocity", 0x606C, 0x00, "DINT", "I"),
+    ("ActualVelocity", 0x606c, 0x00, "DINT", "I"),
+    ("ActualTorque", 0x6077, 0x00, "INT", "I"),
 ]
 
 DEFAULT_RETRIEVE = "    __CIA402Node_%(location)s.axis->%(name)s = *(__CIA402Node_%(location)s.%(name)s);"
--- a/etherlab/EthercatMaster.py	Fri Apr 26 13:59:43 2013 +0200
+++ b/etherlab/EthercatMaster.py	Tue Apr 30 01:31:47 2013 +0200
@@ -256,7 +256,7 @@
             "Ethercat Slave Type", self.GetSlaveTypesLibrary())
         if dialog.ShowModal() == wx.ID_OK:
             type_infos = dialog.GetValueInfos()
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if device is not None:
                 if HAS_MCL and _EthercatCIA402SlaveCTN.NODE_PROFILE in device.GetProfileNumbers():
                     ConfNodeType = "EthercatCIA402Slave"
@@ -287,7 +287,7 @@
         type_infos = slave.getType()
         if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor:
             return False
-        device, alignment = self.GetModuleInfos(type_infos)
+        device, module_extra_params = self.GetModuleInfos(type_infos)
         if slave_profile is not None and slave_profile not in device.GetProfileNumbers():
             return False
         return True
@@ -425,7 +425,7 @@
                         "product_code": slave["product_code"],
                         "revision_number":slave["revision_number"],
                     }
-                    device, alignment = self.GetModuleInfos(type_infos)
+                    device, module_extra_params = self.GetModuleInfos(type_infos)
                     if device is not None:
                         if HAS_MCL and _EthercatCIA402SlaveCTN.NODE_PROFILE in device.GetProfileNumbers():
                             CTNType = "EthercatCIA402Slave"
@@ -519,7 +519,7 @@
         slave = self.GetSlave(slave_pos)
         if slave is not None:
             type_infos = slave.getType()
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if device is not None:
                 infos = type_infos.copy()
                 infos.update({"physics": device.getPhysics(),
@@ -533,7 +533,7 @@
             slave = self.GetSlave(slave_pos)
             if slave is not None:
                 type_infos = slave.getType()
-                device, alignment = self.GetModuleInfos(type_infos)
+                device, module_extra_params = self.GetModuleInfos(type_infos)
         if device is not None:
             entries = device.GetEntriesList(limits)
             entries_list = entries.items()
@@ -560,7 +560,7 @@
     def GetSlaveVariableDataType(self, slave_pos, index, subindex):
         slave = self.GetSlave(slave_pos)
         if slave is not None:
-            device, alignment = self.GetModuleInfos(slave.getType())
+            device, module_extra_params = self.GetModuleInfos(slave.getType())
             if device is not None:
                 entries = device.GetEntriesList()
                 entry_infos = entries.get((index, subindex))
@@ -577,7 +577,7 @@
             type_infos = slave.getType()
             if vendor is not None and ExtractHexDecValue(type_infos["vendor"]) != vendor:
                 continue
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if slave_profile is not None and slave_profile not in device.GetProfileNumbers():
                 continue
             entries.extend(self.GetSlaveVariables(slave_position, limits, device))
@@ -598,7 +598,7 @@
         if slave is not None:
             type_infos = slave.getType()
         
-            device, alignment = self.GetModuleInfos(type_infos)
+            device, module_extra_params = self.GetModuleInfos(type_infos)
             if device is not None:
                 sync_managers = []
                 for sync_manager in device.getSm():
--- a/etherlab/etherlab.py	Fri Apr 26 13:59:43 2013 +0200
+++ b/etherlab/etherlab.py	Tue Apr 30 01:31:47 2013 +0200
@@ -232,9 +232,31 @@
                         "Access": access,
                         "PDOMapping": pdomapping}
 
-DEFAULT_ALIGNMENT = 8
-
 class ModulesLibrary:
+
+    MODULES_EXTRA_PARAMS = [
+        ("pdo_alignment", {
+            "column_label": _("PDO alignment"), 
+            "column_size": 150,
+            "default": 8,
+            "description": _(
+"Minimal size in bits between 2 pdo entries")}),
+        ("max_pdo_size", {
+            "column_label": _("Max entries by PDO"),
+            "column_size": 150,
+            "default": 255,
+            "description": _(
+"""Maximal number of entries mapped in a PDO
+including empty entries used for PDO alignment""")}),
+        ("add_pdo", {
+            "column_label": _("Creating new PDO"), 
+            "column_size": 150,
+            "default": 0,
+            "description": _(
+"""Adding a PDO not defined in default configuration
+for mapping needed location variables
+(1 if possible)""")})
+    ]
     
     def __init__(self, path, parent_library=None):
         self.Path = path
@@ -246,13 +268,13 @@
             self.LoadModules()
         else:
             self.Library = None
-        self.LoadAlignments()
+        self.LoadModulesExtraParams()
     
     def GetPath(self):
         return self.Path
     
-    def GetAlignmentFilePath(self):
-        return os.path.join(self.Path, "alignments.cfg")
+    def GetModulesExtraParamsFilePath(self):
+        return os.path.join(self.Path, "modules_extra_params.cfg")
     
     def LoadModules(self):
         self.Library = {}
@@ -310,14 +332,14 @@
                     if profile_filter is None or profile_filter in device.GetProfileNumbers():
                         product_code = device.getType().getProductCode()
                         revision_number = device.getType().getRevisionNo()
-                        alignment = self.GetAlignment(vendor_id, product_code, revision_number)
+                        module_infos = {"device_type": device_type,
+                                        "vendor": vendor_id,
+                                        "product_code": product_code,
+                                        "revision_number": revision_number}
+                        module_infos.update(self.GetModuleExtraParams(vendor_id, product_code, revision_number))
                         device_infos = {"name": ExtractName(device.getName()),
                                         "type": ETHERCAT_DEVICE,
-                                        "infos": {"device_type": device_type,
-                                                  "vendor": vendor_id,
-                                                  "product_code": product_code,
-                                                  "revision_number": revision_number,
-                                                  "alignment": alignment},
+                                        "infos": module_infos,
                                         "children": []}
                         group_infos["children"].append(device_infos)
                         device_type_occurrences = device_dict.setdefault(device_type, [])
@@ -353,7 +375,7 @@
                     revision_number = ExtractHexDecValue(device_infos.getType().getRevisionNo())
                     if (product_code == ExtractHexDecValue(module_infos["product_code"]) and
                         revision_number == ExtractHexDecValue(module_infos["revision_number"])):
-                        return device_infos, self.GetAlignment(vendor, product_code, revision_number)
+                        return device_infos, self.GetModuleExtraParams(vendor, product_code, revision_number)
         return None, None
     
     def ImportModuleLibrary(self, filepath):
@@ -363,10 +385,10 @@
             return True
         return False
     
-    def LoadAlignments(self):
-        self.Alignments = {}
-        
-        csvfile_path = self.GetAlignmentFilePath()
+    def LoadModulesExtraParams(self):
+        self.ModulesExtraParams = {}
+        
+        csvfile_path = self.GetModulesExtraParamsFilePath()
         if os.path.exists(csvfile_path):
             csvfile = open(csvfile_path, "rb")
             sample = csvfile.read(1024)
@@ -378,40 +400,53 @@
                 if has_header:
                     has_header = False
                 else:
-                    try:
-                        self.Alignments[tuple(map(int, row[:3]))] = int(row[3])
-                    except:
-                        pass
+                    params_values = {}
+                    for (param, param_infos), value in zip(
+                        self.MODULES_EXTRA_PARAMS, row[3:]):
+                        if value != "":
+                            params_values[param] = int(value)
+                    self.ModulesExtraParams[
+                        tuple(map(int, row[:3]))] = params_values
             csvfile.close()
-        
-    def SaveAlignments(self):
-        csvfile = open(self.GetAlignmentFilePath(), "wb")
+    
+    def SaveModulesExtraParams(self):
+        csvfile = open(self.GetModulesExtraParamsFilePath(), "wb")
+        extra_params = [param for param, params_infos in self.MODULES_EXTRA_PARAMS]
         writer = csv.writer(csvfile, delimiter=';')
-        writer.writerow(['Vendor', 'product_code', 'revision_number', 'alignment'])
-        for (vendor, product_code, revision_number), alignment in self.Alignments.iteritems():
-            writer.writerow([vendor, product_code, revision_number, alignment])
+        writer.writerow(['Vendor', 'product_code', 'revision_number'] + extra_params)
+        for (vendor, product_code, revision_number), module_extra_params in self.ModulesExtraParams.iteritems():
+            writer.writerow([vendor, product_code, revision_number] + 
+                            [module_extra_params.get(param, '') 
+                             for param in extra_params])
         csvfile.close()
     
-    def SetAlignment(self, vendor, product_code, revision_number, alignment):
+    def SetModuleExtraParam(self, vendor, product_code, revision_number, param, value):
         vendor = ExtractHexDecValue(vendor)
         product_code = ExtractHexDecValue(product_code)
         revision_number = ExtractHexDecValue(revision_number)
         
-        self.Alignments[tuple([vendor, product_code, revision_number])] = alignment
-        self.SaveAlignments()
-    
-    def GetAlignment(self, vendor, product_code, revision_number):
+        module_infos = (vendor, product_code, revision_number)
+        self.ModulesExtraParams.setdefault(module_infos, {})
+        self.ModulesExtraParams[module_infos][param] = value
+        
+        self.SaveModulesExtraParams()
+    
+    def GetModuleExtraParams(self, vendor, product_code, revision_number):
         vendor = ExtractHexDecValue(vendor)
         product_code = ExtractHexDecValue(product_code)
         revision_number = ExtractHexDecValue(revision_number)
         
-        alignment = self.Alignments.get(tuple([vendor, product_code, revision_number]))
-        if alignment is not None:
-            return alignment
-        
         if self.ParentLibrary is not None:
-            return self.ParentLibrary.GetAlignment(vendor, product_code, revision_number)
-        return DEFAULT_ALIGNMENT
+            extra_params = self.ParentLibrary.GetModuleExtraParams(vendor, product_code, revision_number)
+        else:
+            extra_params = {}
+        
+        extra_params.update(self.ModulesExtraParams.get((vendor, product_code, revision_number), {}))
+        
+        for param, param_infos in self.MODULES_EXTRA_PARAMS:
+            extra_params.setdefault(param, param_infos["default"])
+        
+        return extra_params
 
 USERDATA_DIR = wx.StandardPaths.Get().GetUserDataDir()
 if wx.Platform != '__WXMSW__':
--- a/etherlab/plc_cia402node.c	Fri Apr 26 13:59:43 2013 +0200
+++ b/etherlab/plc_cia402node.c	Tue Apr 30 01:31:47 2013 +0200
@@ -39,10 +39,15 @@
     axis_s* axis;
 } __CIA402Node;
 
-#define AXIS_UNIT_TO_USER_UNIT(param)\
-(IEC_LREAL)(param) * __CIA402Node_%(location)s.axis->RatioDenominator / __CIA402Node_%(location)s.axis->RatioNumerator
-#define USER_UNIT_TO_AXIS_UNIT(param)\
-(IEC_DINT)(param * __CIA402Node_%(location)s.axis->RatioNumerator / __CIA402Node_%(location)s.axis->RatioDenominator)
+#define AXIS_UNIT_TO_USER_UNIT(param, type, name)\
+(IEC_##type)(param) * __CIA402Node_%(location)s.axis->name##RatioDenominator / __CIA402Node_%(location)s.axis->name##RatioNumerator
+#define USER_UNIT_TO_AXIS_UNIT(param, type, name)\
+(IEC_##type)(param * __CIA402Node_%(location)s.axis->name##RatioNumerator / __CIA402Node_%(location)s.axis->name##RatioDenominator)
+
+#define DEFAULT_AXIS_UNIT_TO_USER_UNIT(param) AXIS_UNIT_TO_USER_UNIT(param, LREAL,)
+#define DEFAULT_USER_UNIT_TO_AXIS_UNIT(param) USER_UNIT_TO_AXIS_UNIT(param, DINT,)
+#define TORQUE_AXIS_UNIT_TO_USER_UNIT(param) AXIS_UNIT_TO_USER_UNIT(param, LREAL, Torque)
+#define TORQUE_USER_UNIT_TO_AXIS_UNIT(param) USER_UNIT_TO_AXIS_UNIT(param, INT, Torque)
 
 static __CIA402Node __CIA402Node_%(location)s;
 
@@ -118,8 +123,9 @@
 	__CIA402Node_%(location)s.axis->CommunicationReady = *(__CIA402Node_%(location)s.StatusWord) != 0;
 	__CIA402Node_%(location)s.axis->ReadyForPowerOn = __CIA402Node_%(location)s.state == __SwitchedOn || __OperationEnabled;
 	__CIA402Node_%(location)s.axis->PowerFeedback = __CIA402Node_%(location)s.state == __OperationEnabled;
-	__CIA402Node_%(location)s.axis->ActualPosition = AXIS_UNIT_TO_USER_UNIT(*(__CIA402Node_%(location)s.ActualPosition));
-	__CIA402Node_%(location)s.axis->ActualVelocity = AXIS_UNIT_TO_USER_UNIT(*(__CIA402Node_%(location)s.ActualVelocity));
+	__CIA402Node_%(location)s.axis->ActualPosition = DEFAULT_AXIS_UNIT_TO_USER_UNIT(*(__CIA402Node_%(location)s.ActualPosition));
+	__CIA402Node_%(location)s.axis->ActualVelocity = DEFAULT_AXIS_UNIT_TO_USER_UNIT(*(__CIA402Node_%(location)s.ActualVelocity));
+	__CIA402Node_%(location)s.axis->ActualTorque = TORQUE_AXIS_UNIT_TO_USER_UNIT(*(__CIA402Node_%(location)s.ActualTorque));
 
 	// Extra variables retrieve
 %(extra_variables_retrieve)s
@@ -152,8 +158,23 @@
 	    	break;
 	}
 
+	// CIA402 node modes of operation computation according to axis motion mode
+	switch (__CIA402Node_%(location)s.axis->AxisMotionMode) {
+		case mc_mode_cst:
+			*(__CIA402Node_%(location)s.ModesOfOperation) = 0x0a;
+			break;
+		case mc_mode_csv:
+			*(__CIA402Node_%(location)s.ModesOfOperation) = 0x09;
+			break;
+		default:
+			*(__CIA402Node_%(location)s.ModesOfOperation) = 0x08;
+			break;
+	}
+
 	// Default variables publish
-	*(__CIA402Node_%(location)s.TargetPosition) = USER_UNIT_TO_AXIS_UNIT(__CIA402Node_%(location)s.axis->PositionSetPoint);
+	*(__CIA402Node_%(location)s.TargetPosition) = DEFAULT_USER_UNIT_TO_AXIS_UNIT(__CIA402Node_%(location)s.axis->PositionSetPoint);
+	*(__CIA402Node_%(location)s.TargetVelocity) = DEFAULT_USER_UNIT_TO_AXIS_UNIT(__CIA402Node_%(location)s.axis->VelocitySetPoint);
+	*(__CIA402Node_%(location)s.TargetTorque) = TORQUE_USER_UNIT_TO_AXIS_UNIT(__CIA402Node_%(location)s.axis->TorqueSetPoint);
 
 	// Extra variables publish
 %(extra_variables_publish)s