EFeru/DbcParser

Add support for user defined attributes (BA_)

taylorjdlee opened this issue ยท 10 comments

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

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?

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_ :
NS_DESC_
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_

EFeru commented

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

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

@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.

@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

@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.

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

A

@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?

I close the issue being on the main branch