/// <summary>
        ///
        /// </summary>
        /// <param name="canMessageType">The CAN message type that you want to generate code for</param>
        /// <param name="n">Number of spaces per indent</param>
        /// <param name="o">Indent offset</param>
        /// <returns></returns>
        public static string GenerateCanMessageTypeCode(CanMessageType canMessageType, int o, int n = 4)
        {
            StringBuilder stringBuilder = new StringBuilder();

            //stringBuilder.AppendLine(n * (0 + o), $"");
            stringBuilder.AppendLine(n * (0 + o), $"public static CanMessageType {canMessageType.Name} = new CanMessageType(new List<CanSignalType>{{");
            foreach (var signal in canMessageType.Signals.Values)
            {
                stringBuilder.AppendLine(n * (2 + o), $"CanSignalTypes.{ signal.QualifiedName.Replace(".", "__")},");
            }
            stringBuilder.AppendLine(n * (1 + o), $"}})");

            stringBuilder.AppendLine(n * (0 + o), $"{{");
            stringBuilder.AppendLine(n * (1 + o), $"Comment       = \"{canMessageType.Comment        }\",");
            stringBuilder.AppendLine(n * (1 + o), $"DLC           =   {canMessageType.DLC.ToString() },");
            stringBuilder.AppendLine(n * (1 + o), $"Id            =   {canMessageType.Id.ToString()  },");
            stringBuilder.AppendLine(n * (1 + o), $"Name          = \"{canMessageType.Name           }\",");
            stringBuilder.AppendLine(n * (1 + o), $"QualifiedName = \"{canMessageType.QualifiedName  }\",");
            stringBuilder.AppendLine(n * (1 + o), $"SendingNode   = \"{canMessageType.SendingNode    }\",");
            stringBuilder.AppendLine(n * (0 + o), $"}};");
            stringBuilder.AppendLine(n * (0 + o), $"");


            return(stringBuilder.ToString());
        }
Пример #2
0
        /// <summary>
        /// Use this function to read a .dbc CAN database file.
        /// </summary>
        /// <param name="fullFilePath">Fulle path to the .dbc file</param>
        /// <returns>CanDataBasType object with all the relevant information from the .dbc file</returns>
        public static CanDatabaseType OpenCanDB(string fullFilePath)
        {
            CanDatabaseType canDatabaseType = new CanDatabaseType();

            canDatabaseType.Name = Path.GetFileNameWithoutExtension(fullFilePath);

            // Read the file line by line.
            //System.IO.StreamReader file = new System.IO.StreamReader(fullFilePath);
            var canDbFile = File.ReadAllLines(fullFilePath).ToList();

            List <String> .Enumerator enumerator = canDbFile.GetEnumerator();
            while (enumerator.MoveNext())
            {
                if (enumerator.Current.StartsWith("BU_"))
                {
                    var nodes = ParseDbcNodeDefinition(enumerator.Current);
                    foreach (var node in nodes)
                    {
                        canDatabaseType.Nodes.Add(node);
                    }
                }

                if (enumerator.Current.StartsWith("BO_"))
                {
                    CanMessageType temp = ParseDbcMessageDefinition(enumerator);
                    canDatabaseType.CanMessageTypes.Add(temp.Id, temp);
                }
                if (enumerator.Current.StartsWith("CM_"))
                {
                    ParseDbcCommentField(enumerator.Current, canDatabaseType.CanMessageTypes);
                }
                if (enumerator.Current.StartsWith("BA_DEF_"))
                {
                    ParseDbcAttributeDefinition(enumerator.Current, canDatabaseType);
                }
                if (enumerator.Current.StartsWith("SIG_VALTYPE_"))
                {
                    ParseDbcTypeDefinition(enumerator.Current, canDatabaseType.CanMessageTypes);
                }
            }

            foreach (var message in canDatabaseType.CanMessageTypes.Values)
            {
                message.QualifiedName = message.Name;
                //message.QualifiedName = canDatabaseType.Name + "." + message.Name;
                foreach (var signal in message.Signals.Values)
                {
                    //signal.QualifiedName = canDatabaseType.Name + "." + signal.QualifiedName;
                }
            }

            return(canDatabaseType);
        }
Пример #3
0
        /// <summary>
        /// Handles one CAN message definitioni line from a .dbc file and recursively
        /// calls ParseDbcMessageDefinition to handle CAN signal definition, which will
        /// cause the enumerator to advance.
        /// </summary>
        /// <param name="enumerator">An enumerators that is used to step through the
        /// .dbc file line by line.</param>
        /// <returns>A new CanMessageType object with most fields and all signals populated.</returns>
        protected static CanMessageType ParseDbcMessageDefinition(List <String> .Enumerator enumerator)
        {
            // Field to be populated and returned
            CanMessageType canMessageType = new CanMessageType();

            string line     = enumerator.Current;
            var    segments = line.Split(' ');

            Debug.Assert(segments.Length == 5);

            int id;

            if (Int32.TryParse(segments[1], out id))
            {
                canMessageType.Id = id;
            }
            // TODO: Handle the else-part. What should we do if the parsing fails?

            string name = segments[2].TrimEnd(':');

            canMessageType.Name = name;

            int DLC;

            if (Int32.TryParse(segments[3], out DLC))
            {
                canMessageType.DLC = DLC;
            }
            // TODO: Handle the else-part. What should we do if the parsing fails?

            string SendingNode = segments[4];

            canMessageType.SendingNode = SendingNode;

            while (enumerator.MoveNext())
            {
                if (!enumerator.Current.TrimStart(' ').StartsWith("SG_"))
                {
                    break;
                }
                CanSignalType temp = ParseDcbSignalDefinition(enumerator.Current);
                canMessageType.Signals.Add(temp.Name, temp);
            }

            foreach (var signal in canMessageType.Signals.Values)
            {
                signal.QualifiedName = canMessageType.Name + "." + signal.Name;
            }

            return(canMessageType);
        }
Пример #4
0
        protected static void ParseDbcCommentField(string line, Dictionary <int, CanMessageType> canMessageTypes)
        {
            // Format: CM_ [<BU_|BO_|SG_> [CAN-ID] [SignalName]] "<CommentText>";
            var    segments = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            string comment;
            int    messageId;

            switch (segments[1])
            {
            case "BU_":
                string node = segments[2];
                comment = segments[3].TrimEnd(';').Trim('\"');
                // TODO: Implement node collection and add this information
                break;

            case "BO_":
                comment = segments[3].TrimEnd(';').Trim('\"');
                if (Int32.TryParse(segments[2], out messageId))
                {
                    CanMessageType canMessage = canMessageTypes[messageId];
                    canMessage.Comment = comment;
                }
                break;

            case "SG_":
                string signalName = segments[3];
                comment = segments[4].TrimEnd(';').Trim('\"');
                if (Int32.TryParse(segments[2], out messageId))
                {
                    CanMessageType canMessage = canMessageTypes[messageId];
                    CanSignalType  canSignal  = canMessage.Signals[signalName];
                    canSignal.Comment = comment;
                }
                break;
            }
        }
        public static string GenerateMessageCode(CanMessageType canMessageType, int o, int n = 4)
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.AppendLine(n * (0 + o), $"");

            stringBuilder.AppendLine(n * (0 + o), $"public class {canMessageType.Name }Message : CanMessageExtended<{canMessageType.Name }Message>");
            stringBuilder.AppendLine(n * (0 + o), $"{{");
            stringBuilder.AppendLine(n * (1 + o), $"public {canMessageType.Name }Message() : base()");
            stringBuilder.AppendLine(n * (1 + o), $"{{");
            stringBuilder.AppendLine(n * (2 + o), $"MessageType = CanMessageTypes.{canMessageType.Name};");
            stringBuilder.AppendLine(n * (2 + o), $"Id = {canMessageType.Id};");
            stringBuilder.AppendLine(n * (1 + o), $"}}");

            // TODO: Implement support for IEEE floats
            foreach (var CanSignalType in canMessageType.Signals.Values)
            {
                string type = CanSignalType.GetTypeName();

                string floatException = ""; // This is used to append 'f' for float literals
                if (CanSignalType.Type == SignalType.Float)
                {
                    floatException = "f";
                }

                // Check if any scaling or offsetting is performed. If so, then it only makes sense
                // to treat it as float.
                string originalType = type;
                if (CanSignalType.Offset != 0 || CanSignalType.ScaleFactor != 1)
                {
                    type = "float";
                }
                string boolException1 = "";
                string boolException2 = "";
                if (type == "bool")
                {
                    boolException1 = "!= 0";
                    boolException2 = "? 1 : 0";
                }

                stringBuilder.AppendLine(n * (1 + o), $"public {type} {CanSignalType.Name}()");
                stringBuilder.AppendLine(n * (1 + o), $"{{");
                stringBuilder.AppendLine(n * (2 + o), $"// Get bits from raw data storage and cast");
                stringBuilder.AppendLine(n * (2 + o), $"{originalType} tempValue1 = ({originalType})(ExtractBits(CanSignalTypes.{CanSignalType.QualifiedName.Replace(".", "__")}) {boolException1});");
                stringBuilder.AppendLine(n * (2 + o), $"{type} tempValue2 = ({type}) tempValue1;");
                stringBuilder.AppendLine(n * (2 + o), $"// Apply inverse transform to restore actual value");
                if (CanSignalType.ScaleFactor != 1)
                {
                    stringBuilder.AppendLine(n * (2 + o), $"tempValue2  {CanSignalType.GetMultiplierOperator()}{floatException};");
                }
                if (CanSignalType.Offset != 0)
                {
                    stringBuilder.AppendLine(n * (2 + o), $"tempValue2  {CanSignalType.GetAdditionOperator() }{floatException};");
                }
                stringBuilder.AppendLine(n * (2 + o), $"return tempValue2;");
                stringBuilder.AppendLine(n * (1 + o), $"}}");
                stringBuilder.AppendLine(n * (1 + o), $"");
                stringBuilder.AppendLine(n * (1 + o), $"public void {CanSignalType.Name}({type} value)");
                stringBuilder.AppendLine(n * (1 + o), $"{{");
                stringBuilder.AppendLine(n * (2 + o), $"// Scale and offset value according to signal specification");
                if (CanSignalType.Offset != 0)
                {
                    stringBuilder.AppendLine(n * (2 + o), $"value {CanSignalType.GetSubtractionOperator() }{floatException};");
                }
                if (CanSignalType.ScaleFactor != 1)
                {
                    stringBuilder.AppendLine(n * (2 + o), $"value {CanSignalType.GetDivisionOperator() }{floatException};");
                }
                stringBuilder.AppendLine(n * (2 + o), $"// Cast to integer and prepare for sending");
                stringBuilder.AppendLine(n * (2 + o), $"this.InsertBits(CanSignalTypes.{CanSignalType.QualifiedName.Replace(".", "__")}, (UInt64)(value {boolException2}));");
                stringBuilder.AppendLine(n * (1 + o), $"}}");
            }
            //stringBuilder.AppendLine(n * (1 + o), $"");


            stringBuilder.AppendLine(n * (0 + o), $"}}");
            stringBuilder.AppendLine(n * (0 + o), $"");

            return(stringBuilder.ToString());
        }