EFeru / DbcParser

.NET CAN bus dbc file parser
MIT License
76 stars 28 forks source link

Add support for user defined attributes (BA_) #15

Closed taylorjdlee closed 1 year ago

taylorjdlee commented 2 years ago

Currently the only values that can be pulled for the message class are the ID, ExtID, Name, DLC, Transmitter, Comment, Cycle time and the list of signals.

Though there is a chance a .dbc will have additional columns/values in the case of the j1939.dbc file below there is an additional column for the PGN value of the message titled PGN Decimal

pgn

I propose that an additional variable is added to the Message class so all values for a message can be read regardless of the .dbc file. In this case perhaps we can have a list of strings that contains each column of the message? This future proofs and allows us to extract all the data for each message regadless of the dbc file.

I ask for this change as PGNs are important in the decoding process of J1939 messages. I would propose a PGN variable for the Message class but as PGNs are specifically for the J1939 protocol and aren't present in standard CAN it would be unfeasible

EFeru commented 2 years ago

Just wondering is there a field or info in the dbc that we can use to determine if it is a j1939 or standard dbc?

taylorjdlee commented 2 years ago

Currently both the SPN and Frame format are saved as BA_ in the J1939.dbc file see below

BA "SPN" SG 2560425726 AuxiliaryIOChannel17 4168; BA "SPN" SG 2560425726 AuxiliaryIOChannel18 4167; BA "SPN" SG 2560425726 AuxiliaryIOChannel19 4174; BA "SPN" SG 2560425726 AuxiliaryIOChannel20 4173; BA "SPN" SG 2560425726 AuxiliaryIOChannel21 4172;

BA "VFrameFormat" BO 2560425726 3;

This is the NS field for the J1939.dbc it's pretty much the same as a normal .dbc. So I guess there's no defining feature of a j1939 dbc over a normal CAN dbc. So I guess instead The library should be build to read in all BA fields? I'm not too familiar with .dbc parsing in general so you may have more of an idea.

NS_ : NSDESC CM_ BADEF BA VAL CATDEF CAT_ FILTER BA_DEFDEF EVDATA ENVVARDATA SGTYPE_ SGTYPEVAL BA_DEFSGTYPE BASGTYPE SIG_TYPEREF VALTABLE SIGGROUP SIGVALTYPE SIGTYPEVALTYPE BO_TXBU BA_DEFREL BAREL BA_DEF_DEFREL BU_SGREL BU_EVREL BU_BOREL SG_MULVAL

EFeru commented 2 years ago

Hi @taylorjdlee , I was just wondering if you are willing to work on this and create a PR?

Adhara3 commented 1 year ago

Just wondering is there a field or info in the dbc that we can use to determine if it is a j1939 or standard dbc?

@EFeru be very careful here. Try to stick with a library that parse standard dbc only. If j1939 complies to this standard, ok, if it extends the standard by using standard syntax, ok. If it not standard, then do not mix it with standard stuff. This is a suggestion to avoid messing up the code with tons of ifs and make it not maintainable .

@taylorjdlee could you please provide a full dbc file as an example? Anyway, BA_ attributes will be supported

Cheers A

taylorjdlee commented 1 year ago

@Adhara3 If you go to this github link you can find an example .dbc file https://github.com/nberlette/canbus/blob/main/dbc/j1939.dbc

//Searches the .dbc file for the PGN depending on the value of the PDU Format
//Look here for more information: https://gist.github.com/agmangas/4f8ef5febcb7564274f77c49ccbc0ffb
private Message[] PgnSearch(uint pgn){
    Message[] filteredSelection = new Message[0];
    var pgnBin = Convert.ToString(pgn, 2).PadLeft(24, '0');
    var pduFormatInt = Convert.ToUInt32(pgnBin.Substring(8, 8), 2);
    if(pduFormatInt >= 240){
        //PGN if pduformat >= F0       
        return filteredSelection = dbc
                        .Messages
                        .Where(m => Convert.ToString(m.ID, 2).PadLeft(32, '0').Substring(6, 18) == pgnBin.Substring(6, 18))
                    .ToArray();
    }
    else{
        //PGN if pduformat < F0
        return filteredSelection = dbc
                        .Messages
            .Where(m => Convert.ToString(m.ID, 2).PadLeft(32, '0').Substring(6, 10) == pgnBin.Substring(6, 10))
            .ToArray();
    }
}

This is currently code I've got that can search via PGN for J1939 using the CANID column. So in a way I've somewhat solved this issue. Though being able to search via the PGN column (as seen in the linked .dbc) would also be helpful.

Adhara3 commented 1 year ago

@taylorjdlee ok thanks, I'll use this DBC as an example. It is quite huge so I'll probably take a subset just to make sure the BA_ tag parsing goes in as intended.

Cheers A

taylorjdlee commented 1 year ago

@Adhara3 Whoops realised this issue was also about SPNs (which are part of the signals attributes). So parsing attributes for both messages and signals would be ideal.

Adhara3 commented 1 year ago

@taylorjdlee BA_ tag works with several other tags, if we support BA_ the support will be full and complete, do not worry.

A

Whitehouse112 commented 1 year ago

@EFeru I'm developing this feature but I'd like your opinion before proceed: currently the Message, Signal and Node classes can be created and modified by the user but to make the code more consistent with the functionality of the library (parse dbc file) I would like to make these classes immutable so that the user can use the objects returned by the library without the ability to modify/create them. May I continue in this direction? It makes sense to you or there is some scenarios in which you want the user to be able to create e.g. a signal?

Adhara3 commented 1 year ago

I close the issue being on the main branch