-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make embedded diagnostic more human readable #886
Merged
pattacini
merged 10 commits into
robotology:devel
from
valegagge:feature/DiagnosticParser
Jul 28, 2023
Merged
Changes from 9 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
30e19fd
Add diagnostic formatter and parsers for each diagnostic messages class.
valegagge 7310d51
Add parser rule string to Default Parser
MSECode 6a5edbf
Add missing error class to switch case for error class unique pointer
MSECode b8be782
Define specific parser for errors eoerror_value_SYS_canservices_board…
MSECode 65c3d92
Update all missing messages
MSECode 40d1c49
Add for loops for getting board can address from number of erroneous …
MSECode a4fce66
Fix errors and version - check todos left
MSECode 5e1c3ba
Fix strcat in for loops
MSECode 4612f0b
Fix string initialization when printing base info
MSECode 4e50281
Improve diagnostic parser for eoerror_value_CFG_candiscovery_boardsin…
valegagge File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright (C) Istituto Italiano di Tecnologia (IIT) | ||
* All rights reserved. | ||
* | ||
* This software may be modified and distributed under the terms of the | ||
* BSD-3-Clause license. See the accompanying LICENSE file for details. | ||
*/ | ||
|
||
#include <string> | ||
#include "diagnosticInfo.h" | ||
#include <yarp/os/LogStream.h> | ||
|
||
|
||
using namespace Diagnostic; | ||
|
||
|
||
/**************************************************************************************************************************/ | ||
/****************************************** TimeOfInfo ***************************************************/ | ||
/**************************************************************************************************************************/ | ||
|
||
void TimeOfInfo::toString(std::string &str_toi) | ||
{ | ||
char str[50]; | ||
snprintf(str, sizeof(str), "%ds %dm %du", sec, msec, usec); | ||
str_toi.clear(); | ||
str_toi.append(str); | ||
} | ||
|
||
|
||
|
||
/**************************************************************************************************************************/ | ||
/****************************************** Info ***************************************************/ | ||
/**************************************************************************************************************************/ | ||
|
||
void EmbeddedInfo::printMessage() | ||
{ | ||
std::string str_toi; | ||
timeOfInfo.toString(str_toi); | ||
|
||
std::string final_str = "from BOARD " + sourceBoardIpAddrStr + " (" + sourceBoardName +") time=" + str_toi + " : " + finalMessage; | ||
switch(severity) | ||
{ | ||
case SeverityOfError::info: | ||
{ | ||
yInfo() << final_str; | ||
} break; | ||
|
||
case SeverityOfError::debug: | ||
{ | ||
yDebug() << final_str; | ||
} break; | ||
|
||
case SeverityOfError::warning: | ||
{ | ||
yWarning() << final_str; | ||
} break; | ||
|
||
case SeverityOfError::error: | ||
{ | ||
yError() << final_str; | ||
} break; | ||
|
||
case SeverityOfError::fatal: | ||
{ | ||
yError() << "EMS received the following FATAL error: " <<final_str; | ||
} break; | ||
|
||
default: | ||
{ | ||
yError() << final_str; | ||
} break; | ||
} | ||
|
||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright (C) 2006-2018 Istituto Italiano di Tecnologia (IIT) | ||
* All rights reserved. | ||
* | ||
* This software may be modified and distributed under the terms of the | ||
* BSD-3-Clause license. See the accompanying LICENSE file for details. | ||
*/ | ||
|
||
|
||
#ifndef __diagnosticInfo_h__ | ||
#define __diagnosticInfo_h__ | ||
|
||
#include <string> | ||
|
||
|
||
namespace Diagnostic { | ||
enum class SeverityOfError {info=0, debug =1, warning =2, error=3, fatal=4}; //TBD | ||
class EmbeddedInfo; | ||
class TimeOfInfo; | ||
} | ||
|
||
class Diagnostic::TimeOfInfo | ||
{ | ||
public: | ||
uint32_t sec; | ||
uint32_t msec; | ||
uint32_t usec; | ||
|
||
void toString(std::string &str_toi); | ||
|
||
}; | ||
|
||
|
||
class Diagnostic::EmbeddedInfo | ||
{ | ||
public: | ||
std::string sourceBoardIpAddrStr; // is the ipv4 address, in string, of the board that sends the diagnostic information | ||
std::string sourceBoardName; // is the name of the board that sends the diagnostic information | ||
std::string sourceCANPortStr; // if the diagnostic info si sent by a board on CAN, this field contains the CAN port expressed in string | ||
uint8_t sourceCANBoardAddr; // if the diagnostic info is sent by a board on CAN, this field contains the CAN address of the board | ||
std::string finalMessage; // contains the final diagostic message after the parsering | ||
Diagnostic::SeverityOfError severity; // is the severity of the message | ||
Diagnostic::TimeOfInfo timeOfInfo; //it is the time of the board when it sent the message | ||
std::string axisName; //if the error contains the joint number, then axisName contain its name. | ||
|
||
public: | ||
void printMessage(); | ||
}; | ||
|
||
|
||
|
||
#endif //__diagnosticInfo_h__ |
161 changes: 161 additions & 0 deletions
161
src/libraries/icubmod/embObjLib/diagnosticInfoFormatter.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* | ||
* Copyright (C) Istituto Italiano di Tecnologia (IIT) | ||
* All rights reserved. | ||
* | ||
* This software may be modified and distributed under the terms of the | ||
* BSD-3-Clause license. See the accompanying LICENSE file for details. | ||
*/ | ||
|
||
#include <string> | ||
#include "diagnosticLowLevelFormatter.h" | ||
#include "diagnosticLowLevelFormatter_hid.h" | ||
|
||
|
||
|
||
using namespace Diagnostic::LowLevel; | ||
using namespace Diagnostic; | ||
|
||
|
||
InfoFormatter::InfoFormatter(eth::TheEthManager* ethManager, eOmn_info_basic_t* infobasic, uint8_t * extra, const EOnv* nv, const eOropdescriptor_t* rd) : | ||
m_ethManager(ethManager),m_infobasic(infobasic), m_extra(extra), m_nv(nv), m_rd(rd) | ||
{;} | ||
|
||
|
||
bool InfoFormatter::getDiagnosticInfo(EmbeddedInfo &info) | ||
{ | ||
//==> firts of all fill all the common info to all messages and then parser the parameter depending on the specific message | ||
|
||
AuxEmbeddedInfo dnginfo; | ||
|
||
//1. fill all the common info to all messages | ||
dnginfo.sourceBoardIpAddr = eo_nv_GetIP(m_nv); | ||
dnginfo.baseInfo.sourceBoardName = m_ethManager->getName(eo_nv_GetIP(m_nv)); | ||
getTimeOfInfo(dnginfo.baseInfo.timeOfInfo); | ||
getSourceOfMessage(dnginfo.baseInfo); | ||
getSeverityOfError(dnginfo.baseInfo); | ||
|
||
dnginfo.baseMessage = std::string(eoerror_code2string(m_infobasic->properties.code)); | ||
|
||
eOmn_info_extraformat_t extraf = static_cast<eOmn_info_extraformat_t>EOMN_INFO_PROPERTIES_FLAGS_get_extraformat(m_infobasic->properties.flags); | ||
dnginfo.extraMessage.clear(); | ||
|
||
if(eomn_info_extraformat_verbal == extraf) | ||
{ | ||
dnginfo.extraMessage.append((NULL == m_extra) ? ("no extra info despite we are in verbal mode") : ((const char *)m_extra)); | ||
} | ||
else | ||
{ | ||
dnginfo.extraMessage.append("."); | ||
} | ||
|
||
|
||
ipv4ToString(dnginfo.baseInfo); | ||
dnginfo.param64 = m_infobasic->properties.par64; | ||
dnginfo.param16 = m_infobasic->properties.par16; | ||
dnginfo.errorCode = m_infobasic->properties.code; | ||
|
||
EntityNameProvider entityNameProvider{dnginfo.sourceBoardIpAddr, m_ethManager}; | ||
|
||
//2. create the parser related to the error cod family | ||
std::unique_ptr<DefaultParser> parser_ptr; | ||
|
||
eOerror_category_t category = eoerror_code2category(m_infobasic->properties.code); | ||
switch(category) | ||
{ | ||
case eoerror_category_Config: parser_ptr = std::make_unique<ConfigParser>(dnginfo, entityNameProvider); break; | ||
|
||
case eoerror_category_MotionControl: parser_ptr = std::make_unique<MotionControlParser>(dnginfo, entityNameProvider); break; | ||
|
||
case eoerror_category_HardWare: parser_ptr = std::make_unique<HwErrorParser>(dnginfo, entityNameProvider); break; | ||
|
||
case eoerror_category_System: parser_ptr = std::make_unique<SysParser>(dnginfo, entityNameProvider); break; | ||
|
||
case eoerror_category_ETHmonitor: parser_ptr = std::make_unique<EthMonitorParser>(dnginfo, entityNameProvider); break; | ||
|
||
case eoerror_category_Skin: parser_ptr = std::make_unique<SkinParser>(dnginfo, entityNameProvider); break; | ||
|
||
case eoerror_category_InertialSensor: parser_ptr = std::make_unique<InertialSensorParser>(dnginfo, entityNameProvider); break; | ||
|
||
case eoerror_category_AnalogSensor: parser_ptr = std::make_unique<AnalogSensorParser>(dnginfo, entityNameProvider); break; | ||
|
||
default: parser_ptr = std::make_unique<DefaultParser>(dnginfo, entityNameProvider); break; | ||
}; | ||
|
||
parser_ptr->parseInfo(); | ||
|
||
//3. return the parsered info | ||
info = dnginfo.baseInfo; | ||
|
||
return true; | ||
|
||
} | ||
|
||
void InfoFormatter::getSourceOfMessage(EmbeddedInfo &info) | ||
{ | ||
const char * const sourcenames[] = | ||
{ | ||
"LOCAL", | ||
"CAN1", | ||
"CAN2", | ||
"UNKNOWN" | ||
}; | ||
|
||
eOmn_info_source_t source = static_cast<eOmn_info_source_t>EOMN_INFO_PROPERTIES_FLAGS_get_source(m_infobasic->properties.flags); | ||
|
||
info.sourceCANBoardAddr = EOMN_INFO_PROPERTIES_FLAGS_get_address(m_infobasic->properties.flags); | ||
|
||
info.sourceCANPortStr = std::string(((source > eomn_info_source_can2) ? (sourcenames[3]) : (sourcenames[source]))); | ||
|
||
} | ||
|
||
|
||
|
||
void InfoFormatter::getTimeOfInfo(TimeOfInfo &timeOfInfo) | ||
{ | ||
timeOfInfo.sec = m_infobasic->timestamp / 1000000; | ||
timeOfInfo.msec = (m_infobasic->timestamp % 1000000) / 1000; | ||
timeOfInfo.usec = m_infobasic->timestamp % 1000; | ||
} | ||
|
||
|
||
void InfoFormatter::ipv4ToString(EmbeddedInfo &info) | ||
{ | ||
char ipinfo[20] = {0}; | ||
eo_common_ipv4addr_to_string(eo_nv_GetIP(m_nv), ipinfo, sizeof(ipinfo)); | ||
info.sourceBoardIpAddrStr.clear(); | ||
info.sourceBoardIpAddrStr.append(ipinfo); | ||
} | ||
|
||
void InfoFormatter::getSeverityOfError(EmbeddedInfo &info) | ||
{ | ||
eOmn_info_type_t type = static_cast<eOmn_info_type_t>EOMN_INFO_PROPERTIES_FLAGS_get_type(m_infobasic->properties.flags); | ||
switch(type) | ||
{ | ||
case eomn_info_type_info: {info.severity = SeverityOfError::info;return;} | ||
case eomn_info_type_debug: {info.severity = SeverityOfError::debug;return;} | ||
case eomn_info_type_warning: {info.severity = SeverityOfError::warning;return;} | ||
case eomn_info_type_error: {info.severity = SeverityOfError::error;return;} | ||
case eomn_info_type_fatal: {info.severity = SeverityOfError::fatal;return;} | ||
|
||
|
||
}; | ||
} | ||
|
||
/**************************************************************************************************************************/ | ||
/****************************************** EntityNameProvider ***************************************************/ | ||
/**************************************************************************************************************************/ | ||
EntityNameProvider::EntityNameProvider(eOipv4addr_t boardAddr, eth::TheEthManager* ethManager):m_ethManager(ethManager) | ||
{ | ||
m_MC_ethRes = m_ethManager->getInterface(boardAddr, eth::iethresType_t::iethres_motioncontrol); | ||
} | ||
|
||
bool EntityNameProvider::getAxisName(uint32_t entityId, std::string &axisName) | ||
{ | ||
if(m_MC_ethRes == nullptr) | ||
{ | ||
axisName = "N/A"; | ||
return false; | ||
} | ||
|
||
return (m_MC_ethRes->getEntityName(entityId, axisName)); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inside
switch(category)
the pointerparser_ptr
uses a class that is created and then destroyed at each call of this functiongetDiagnosticInfo()
which is called at the reception of every diagnostics message received byyarprobotinterface
, so potentially many times every ms.That could be heavy.
To avoid the continuous creation and destruction of the classes, an instance of
ConfigParser
,MotionControlParser
etc could be created at startup and stay alive for the whole life ofyarprobotinterface
. The functiongetDiagnosticInfo()
would just assign toparser_ptr
the pointer to the relevant class.