update vss_util tool (#2)

This commit is contained in:
tompzf
2025-11-12 15:40:23 +01:00
committed by GitHub
parent 6ed4b1534e
commit 2fb043b2be
37 changed files with 485 additions and 179 deletions

View File

@@ -32,13 +32,14 @@ void CCSVFileReader::Help()
std::cout << " [required] Column 'CAN name' must contain a character '.' (for vehicle device signal)." << std::endl;
std::cout << " [required] Last column: in case of vehicle device it is 'CAN name'." << std::endl;
std::cout << " [required] Last column: in case of basic service it is avss from vehicle device." << std::endl;
std::cout << " [optional] additonal column: c++ code to recalulate the signal value in the vehicle device." << std::endl;
std::cout << " [recommended] Cells may be empty. In that case either a default string is created or previous entry is used." << std::endl;
std::cout << " [recommended] Column Class name should start with uppercase character." << std::endl;
std::cout << " [recommended] Column Function name should start with uppercase character." << std::endl;
std::cout << " [recommended] Column Signal name should start with lowercase character." << std::endl;
std::cout << "Summary can be found in file 'summary.txt'." << std::endl;
std::cout << "Columns:" << std::endl;
std::cout << "Device Type ';' Class name ';' Function name ';' Signal name ';' Interface (vss) ';' Direction ';' Signal value type ';' 'CAN name' or Interface(vss)" << std::endl;
std::cout << "Device Type ';' Class name ';' Function name ';' Signal name ';' Interface (vss) ';' Direction ';' Signal value type ';' 'CAN name' or Interface(vss); Formula (is optional, normally empty)" << std::endl;
std::cout << std::endl;
std::cout << "e.g." << std::endl;
std::cout << "VD ';' FrontWheel ';' SetAverageAngle ';' averageAngle ';' Vehicle.Chassis.Axle.Row.Wheel.AverageAngle ';' RX ';' float ';' CANMsg.Angle" << std::endl;
@@ -82,7 +83,28 @@ void CCSVFileReader::ReadLine(const std::string& ssLine, const uint32_t index, s
{
item = Trim(item);
auto cType = GetCTypeFromIDLType(item); // maybe its a IDL type
if (MustNotContainSpaces(item) || (cType.size() != 0))
if ((parts.size() == (vssVDColumns::column_vdFormula)) && !item.empty())
{
// we have the formula column, if not empty, collect everything
auto collectItem = item;
while (std::getline(ss, item, ';'))
{
collectItem.append(";");
collectItem.append(item);
}
// Remove " from front and end
if (!collectItem.empty() && collectItem.front() == '"' && collectItem.back() == '"') {
collectItem = collectItem.substr(1, collectItem.size() - 2);
}
// Replace all occurrences of "" with "
collectItem = std::regex_replace(collectItem, std::regex("\"\""), "\"");
parts.push_back(collectItem);
}
else if (MustNotContainSpaces(item) || (cType.size() != 0))
{
parts.push_back(item);
}
@@ -94,6 +116,10 @@ void CCSVFileReader::ReadLine(const std::string& ssLine, const uint32_t index, s
}
}
}
if (parts.size() == (endColumn - 1))
{
parts.push_back("");
}
if (parts.size() >= endColumn)
{
ParseColumns(parts, index);
@@ -140,7 +166,7 @@ void CCSVFileReader::ParseColumns(const std::vector<std::string>& parts, const u
signal.className = GenerateDefaultIfEmpty(parts[vssVDColumns::column_className], "ClassName", index);
if (AddFunctionVDDefinition(signal, parts[vssVDColumns::column_functionName], parts[vssVDColumns::column_signalName],
parts[vssVDColumns::column_canSignalName], parts[vssVDColumns::column_signalCType], index))
parts[vssVDColumns::column_canSignalName], parts[vssVDColumns::column_signalCType], parts[vssVDColumns::column_vdFormula], index))
{
ValidateVDCodeStyle(signal, m_verbose);
m_vdSignals.push_back(signal);
@@ -185,7 +211,7 @@ bool CCSVFileReader::AddToExistingVDSignal(std::vector <SSignalVDDefinition>& si
AddFunctionVDDefinition(signal, parts[vssVDColumns::column_functionName], parts[vssVDColumns::column_signalName],
parts[vssVDColumns::column_canSignalName], parts[vssVDColumns::column_signalCType], index);
parts[vssVDColumns::column_canSignalName], parts[vssVDColumns::column_signalCType], parts[vssVDColumns::column_vdFormula], index);
return true;
}
}
@@ -215,7 +241,7 @@ bool CCSVFileReader::AddToExistingBSSignal(std::vector <SSignalBSDefinition>& si
}
bool CCSVFileReader::AddFunctionVDDefinition(SSignalVDDefinition& signal, const std::string& functionName, const std::string& signalName,
const std::string& canSignalName, const std::string& idlType, const uint32_t index)
const std::string& canSignalName, const std::string& idlType, const std::string& formula, const uint32_t index)
{
if (!MustContainDotOrIsEmpty(canSignalName, true)) // can signal must must not be empty
{
@@ -238,6 +264,7 @@ bool CCSVFileReader::AddFunctionVDDefinition(SSignalVDDefinition& signal, const
func.signalName = GenerateDefaultIfEmpty(signalName, "variableName", index);
func.canSignalName = canSignalName;
func.idlType = idlType;
func.formula = formula;
ValidateVDCodeStyle(func, m_verbose);
signal.vecFunctions.push_back(func);

View File

@@ -2,6 +2,7 @@
#define CSV_FILE_READER_H
#include <fstream>
#include <regex>
#include "vss_helper.h"
@@ -54,6 +55,7 @@ private:
column_signalCType,
column_canSignalName,
column_vdDefinition = column_canSignalName,
column_vdFormula,
column_end
} vssVDColumns;
@@ -116,11 +118,12 @@ private:
* @param[in] signalName signal name
* @param[in] canSignalName can signal name
* @param[in] idlType idl type
* @param[in] formula code to convert signal value in vehicle device
* @param[in] index line number
* @return True if function definition was added, otherwise false
*/
bool AddFunctionVDDefinition(SSignalVDDefinition& signal, const std::string& functionName,
const std::string& signalName, const std::string& canSignalName, const std::string& idlType, const uint32_t index);
bool AddFunctionVDDefinition(SSignalVDDefinition& signal, const std::string& functionName, const std::string& signalName,
const std::string& canSignalName, const std::string& idlType, const std::string& formula, const uint32_t index);
/**
* @brief add function definition to the container of an existing signal (basic service)

View File

@@ -79,7 +79,7 @@ extern "C" int main(int iArgc, const char* rgszArgv[])
rArgVerboseDef.AddSubOptionName("verbose");
cmdln.DefineSubOption("prefix", ssPrefix, "prefix, used by cmake library and signal definition in signal_identifier.h file.");
cmdln.DefineSubOption("enable_components", bEnableComponents, "Creates additionally to the idl files the code for the components.");
cmdln.DefineSubOption("version", ssVersion, "Optional: version information of the dbc file.");
cmdln.DefineSubOption("version", ssVersion, "Optional: version information for the created files.");
cmdln.DefineOption("O", pathOutputDir, "Set output directory (required).");
cmdln.DefineDefaultArgument(ssVSSFileName, "Excel file.");
cmdln.Parse(static_cast<size_t>(iArgc), rgszArgv);

View File

@@ -140,6 +140,7 @@ public:
std::string functionName; ///< signal value set function name
std::string signalName; ///< signal name
std::string canSignalName; ///< can signal name (combination of signak messages and signal name)
std::string formula; ///< c++ code if the value has to be converted
};
/**

View File

@@ -418,6 +418,27 @@ std::string CVSSVDCodingRX::Code_VD_RXRegister( const std::string& class_name, c
mapKeywords["signal_name"] = function.signalName;
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
mapKeywords["class_name_lowercase"] = class_name_lowercase;
if (!function.formula.empty())
{
auto formula = " " + function.formula;
std::string target = ";";
std::string replacement = ";\n";
size_t pos = 0;
while ((pos = formula.find(target, pos)) != std::string::npos)
{
formula.replace(pos, target.length(), replacement);
pos += replacement.length();
}
mapKeywords["convertFormula"] = formula;
}
else
{
std::stringstream formula;
formula << Code_VD_RXFormular(function);
mapKeywords["convertFormula"] = formula.str();
}
return ReplaceKeywords(R"code(
/**
@@ -452,13 +473,7 @@ void CVehicleDevice%class_name%::Unregister%function_name%Event(vss::%vssWithCol
*/
void CVehicleDevice%class_name%::ExecuteAllCallBacksFor%start_with_uppercase%(sdv::any_t value)
{
%value_ctype% %signal_name% = value.get<%value_ctype%>();
//
// TODO:
// Convert vehicle specific value to abstract unit/range
//
%convertFormula%
std::lock_guard<std::mutex> lock(m_%signal_name%MutexCallbacks);
for (const auto& callback : m_%signal_name%Callbacks)
{
@@ -467,3 +482,18 @@ void CVehicleDevice%class_name%::ExecuteAllCallBacksFor%start_with_uppercase%(sd
}
)code", mapKeywords);
}
std::string CVSSVDCodingRX::Code_VD_RXFormular(const SFunctionVDDefinition& function) const
{
CKeywordMap mapKeywords;
mapKeywords["signal_name"] = function.signalName;
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
return ReplaceKeywords(R"code( %value_ctype% %signal_name% = value.get<%value_ctype%>();
//
// TODO:
// Convert vehicle specific value to abstract unit/range
//
)code", mapKeywords);
}

View File

@@ -143,6 +143,13 @@ protected:
std::string Code_VD_RXRegister(const std::string& class_name, const SFunctionVDDefinition& function,
const std::string& vssWithColons) const;
/**
* @brief create code to get the value or use use user defined c++ code
* @param[in] function function definition structure
* @return default code to get the value
*/
std::string Code_VD_RXFormular(const SFunctionVDDefinition& function) const;
std::string m_ssPrefix; ///< prefix, used by cmake library and signal definition in signal_identifier.h file.
};