CANopenNode / CANopenEditor

CANopen Object Dictionary Editor
GNU General Public License v3.0
115 stars 57 forks source link

Proposal for the new internal CANopen device database. #112

Closed CANopenNode closed 1 month ago

CANopenNode commented 1 month ago

Currently CANopenEditor is quite rich application, but becomes complex and hard to maintain and to grow. So we decided to dig into foundation and try to implement new structure for the classes describing CANopen device. Currently this code is inside eds.cs file. And it is the central part of each exporter, GUI, etc. The final goal is to replace eds.cs file with this proposal. Some discussion already started at https://github.com/CANopenNode/CANopenEditor/pull/104.

Please take a look into file libEDSsharp/CanOpenDevice.cs . It is quite descriptive and should contain all, what CANopenEditor currently offers.

Here is an example program for quick testing this file:

class Program
{
    static void Main()
    {
        libEDSsharp.CanOpenDevice dev = new libEDSsharp.CanOpenDevice();

        var obj2000 = new libEDSsharp.OdEntry{
            Disabled = true,
            ParameterName = "Custom object",
            Denotation = "Another name",
            Description = "Testing",
            ObjectType = libEDSsharp.ObjectType.VAR,
            CountLabel = "LABEL_1",
            StorageGroup = "XY",
            FlagsPDO = true
        };
        var obj2000_00 = new libEDSsharp.OdSubEntry{
            DataType = libEDSsharp.DataType.UNSIGNED32,
            AccessSDO = libEDSsharp.AccessSDO.ro,
            AccessPDO = libEDSsharp.AccessPDO.no,
            AccessSRDO = libEDSsharp.AccessSRDO.tx,
            DefaultValue = "123",
            ParameterValue = "0",
            LowLimit = "0",
            HighLimit = "0",
            StringLengthMin = 1
        };
        obj2000.SubObjects.Add("00", obj2000_00);

        dev.Objects.Add("2000", obj2000);

        var jsonString = dev.ToJson();

        Console.WriteLine(jsonString);

        libEDSsharp.CanOpenDevice dev2 = new libEDSsharp.CanOpenDevice(jsonString);

        Console.WriteLine(dev2.ToJson());
    }
}

And here is the result in JSON:

{
  "FileInfo": {
    "FileVersion": "",
    "Description": "",
    "CreationTime": "0001-01-01T00:00:00",
    "CreatedBy": "",
    "ModificationTime": "0001-01-01T00:00:00",
    "ModifiedBy": ""
  },
  "DeviceInfo": {
    "VendorName": "",
    "VendorNumber": 0,
    "ProductName": "",
    "ProductNumber": 0,
    "BaudRate_10": true,
    "BaudRate_20": true,
    "BaudRate_50": true,
    "BaudRate_125": true,
    "BaudRate_250": true,
    "BaudRate_500": true,
    "BaudRate_800": false,
    "BaudRate_1000": true,
    "Granularity": 8,
    "NrOfRxPDO": 4,
    "NrOfTxPDO": 4,
    "LssSlave": true,
    "LssMaster": false,
    "NodeGuardingSlave": false,
    "NodeGuardingMaster": false,
    "NrOfNodeGuardingMonitoredNodes": 0
  },
  "DeviceComissioning": {
    "NodeID": 0,
    "NodeName": "",
    "Baudrate": 0,
    "NetNumber": 0,
    "NetworkName": "",
    "CANopenManager": false,
    "LSS_SerialNumber": 0
  },
  "Objects": {
    "2000": {
      "Disabled": true,
      "ParameterName": "Custom object",
      "Denotation": "Another name",
      "Description": "Testing",
      "ObjectType": "VAR",
      "CountLabel": "LABEL_1",
      "StorageGroup": "XY",
      "FlagsPDO": true,
      "SubObjects": {
        "00": {
          "DataType": "UNSIGNED32",
          "AccessSDO": "ro",
          "AccessPDO": "no",
          "AccessSRDO": "tx",
          "DefaultValue": "123",
          "ParameterValue": "0",
          "LowLimit": "0",
          "HighLimit": "0",
          "StringLengthMin": 1
        }
      }
    }
  }
}

@trojanobelix, @nimrof or others, some comments, ideas...

--Janez

trojanobelix commented 1 month ago

I find this very elegant and I like the idea of displaying all the information of a CAN device in this way. I particularly like the fact that there are no dependencies on the exporters. It should also be clear which CiA DS requires the info block just described. But a comment is probably sufficient.

For me, this is the right way to go.

CANopenNode commented 1 month ago

Thank you for the comment. I tried to design structure of the json properties very carefully. It was hard from the start, but now I'm quite satisfied. Standards are not always precise and some information are duplicated there. I hope, CANopenEditor's internal database will stay clear.

I will try to migrate exporters, with no hurry. Some future comments will be very helpful.

nimrof commented 1 month ago

Hi, Sorry for my late reply. Looks good to me and i do like that you have split index & subindex.

One big thing i have been thinking about since you talked about how json would make it easier to work with the file in python. What about using protobuffer with json serialize? That way python (c/c++,go,rust+++) could work with the structure more easier as it would get access to the enum, class and lists/dictionary and the output would look very similar to what it does now.

Its more work to get up and running, but if working with the files from python is a big reason for the change it might be worth

CANopenNode commented 1 month ago

What about using protobuffer with json serialize?

I don't know. As I understand, protobuf is an alternative to json. Python and others may have more native access to data, faster, more modern. But json is very easy to use and also json file is easy to read. There are pros and cons. I don't have plans for some heavy use with python.

For example, use of the above json data is already simple, also for beginners:

import json
s = '{"FileInfo":{"FileVer ... }'
dev = json.loads(s)
dev['Objects']['2000']['SubObjects']['00']['AccessSDO']
# gives 'ro'
CANopenNode commented 1 month ago

I was thinking about protobuf some more. At the end it may have benefits over json. We have to specify a proto definition, classes for c# or python are auto generated. I'm new to protobuf, this blog also seems interesting to me.

nimrof commented 1 month ago

I was thinking about protobuf some more. At the end it may have benefits over json. We have to specify a proto definition, classes for c# or python are auto generated. I'm new to protobuf, this blog also seems interesting to me.

I can try to make a draft PR. with a basic c# setup and some enums & classes/messages if you want? Its a little hectic in my life at the moment so it may take a few days

CANopenNode commented 1 month ago

It is the same with me. Luckily we don't need to hurry with this.

trojanobelix commented 1 month ago

You guys are really awesome. I'm sorry that I can't support you because of my lack of knowledge in object-orientated programming.

But I have a guilty conscience, this will have to do. ;-)

nimrof commented 1 month ago

But I have a guilty conscience, this will have to do. ;-)

Do not feel guilty. I appreciate your and Janez support (not just code support) and i did not think any of you should have guilty conscience

CANopenNode commented 1 month ago

@trojanobelix, don't worry, you have experience with different CANopen tools, eds files, etc. And this may be quite valuable at some point.

Properties from JSON database presented above may be all we need for CANopen device and are reduced to minimum, according to my selection. But some properties may be missing. For example, I don't know what to do with "module support" in eds files? Is it safe just to skip it? Also, some time ago, we discussed about removing some outdated exporters and we found optimal solution, I think.

trojanobelix commented 1 month ago

I think we should keep module support. Janez, I know you commented it out recently. I didn't quite understand why?

But I'm not sure how module support is defined in the CiA standard.

CANopenNode commented 1 month ago

Yes, there was a tab in GUI for module support. Removal is here: https://github.com/CANopenNode/CANopenEditor/commit/43592ba22ea9438d3f9987d60a371aa47d56c1d8 (My cleanup at that time, but don't know how to add a tab back).

If we add it back and is working as expected, then it is no problem, we will just add it to the new database.

I think, modules are specified only in CiA306(eds). In CiA301 there is only an OD entry "Module List". I have no experience with modules, maybe you can do some tests with eds and modules @trojanobelix?

trojanobelix commented 1 month ago

I have no experience with it either.

But I know that someone once sent me an extremely large EDS with many modules in this context. I think it was from Maxxon Motors. If I remember correctly, it contained all the different motor variants as modules.

I think the module view then allows you to select the relevant module(s).

We can take another look at the old implementation of Robincornelius.

But it seems to make sense for this use case. Without module EDS data will probably not be usable. It is certainly not a high priority, but it would be good to consider this in the new concept, as long as it does not mean too much effort.

trojanobelix commented 1 month ago

Module file ist here: #69

Know problem (from eds.cs) //FIXME Count "If several modules are gathered to form a new Sub-Index, //then the number is 0, followed by semicolon and the //number of bits that are created per module to build a new Sub-Index" // CiA Draft Standard Proposal 306

    [EdsExport]
    public byte count = 0;
nimrof commented 1 month ago

Hi, added protobuffer testcode at #115.