32 namespace canopen_schunk {
51 <<
". Update ignored." <<
endl);
59 ss <<
"Unexpected length " <<
static_cast<int>(msg.
dlc) <<
" of EMCY message. Expected 8.";
69 for (
size_t i = 3; i < 8; ++i)
78 <<
" is now in state error free." <<
endl);
84 ss <<
"EMCY message states that an error in node " 85 <<
static_cast<int>(
m_node_id) <<
" occured: " 117 std::stringstream ss;
120 uint16_t subcode = error_code & nibble_validator;
121 std::map<uint16_t, std::string>::iterator map_it =
m_eec_map.find(subcode);
124 ss << map_it->second << std::endl;
125 uint16_t nibble_validator_next = nibble_validator >> 4;
126 uint16_t next_nibble = error_code & nibble_validator_next;
131 while (next_nibble == 0 && nibble_validator_next > 0)
133 subcode |= next_nibble;
134 nibble_validator += nibble_validator_next;
135 nibble_validator_next = nibble_validator_next >> 4;
136 next_nibble = error_code & nibble_validator_next;
140 while ((map_it->first & nibble_validator) == subcode)
142 if ( (map_it->first & nibble_validator_next) == next_nibble )
145 while ((map_it->first & nibble_validator_next) != 0 && subcode != error_code)
147 subcode |= next_nibble;
148 nibble_validator += nibble_validator_next;
149 nibble_validator_next = nibble_validator_next >> 4;
150 next_nibble = error_code & nibble_validator_next;
153 if ( (map_it->first - subcode) == 0 )
156 ss << map_it->second << std::endl;
163 if (subcode != error_code)
165 ss <<
"Error code could not be fully parsed. Full error code was " <<
hexToString(error_code) << std::endl;
172 std::stringstream ss;
173 ss <<
"Unknown emergency error code: " <<
hexToString(error_code);
180 std::stringstream ss;
184 ss <<
"No error register description set. Returning plain register code: " 189 for (
size_t i = 0; i < (
sizeof(error_code) * 8); ++i)
191 uint8_t bit = (0x01 << i) & error_code;
195 ss << map_it->second <<
", ";
200 if (ss.str().empty())
202 ss <<
"Unknown error register code: " <<
hexToString(error_code);
216 for (std::map<uint32_t, std::string>::iterator it = new_entries.begin();
217 it != new_entries.end();
228 for (std::map<uint32_t, std::string>::iterator it = new_entries.begin();
229 it != new_entries.end();
239 std::vector<uint8_t> uploaded_data;
240 sdo.
upload(
false, 0x1003, error_nr, uploaded_data);
242 if (uploaded_data.size() != 4)
244 throw ProtocolException (0x1003, error_nr,
"Uploaded data size does not match 4");
247 uint16_t eec = uploaded_data[0] + (uploaded_data[1] << 8);
248 uint16_t additional_information = uploaded_data[2] + (uploaded_data[3] << 8);
250 std::stringstream ss;
251 ss <<
" Error " <<
static_cast<int>(error_nr) <<
": " 253 <<
"Additional information: " <<
hexToString(additional_information);
262 sdo.
upload(
false, 0x1003, 0, num_errors);
267 for (
size_t i = 1; i <= num_errors; ++i)
278 sdo.
download(
false, 0x1003, 0, value);
static std::string lookupEECString(const uint16_t error_code)
#define LOGGING_INFO_C(streamname, classname, arg)
void printLastErrors(SDO &sdo)
Print all errors present in error register 0x1003.
eEMCY_STATUS m_error_state
static void addEmergencyErrorMap(const std::string &filename, const std::string &block_identifier)
Adds new information from an ini file to the emergency error map.
void clearErrorHistory(SDO &sdo)
Clear the error register 0x1003.
virtual void update(const CanMsg &msg)
update Updates the EMCY object with a received EMCY Message
std::string hexArrayToString(const unsigned char *msg, const uint8_t length)
Transforms an array of unsigned chars into a string of Hex representations of those chars...
uint16_t m_eec
emergency_error_code;
Basic CanOpen exception that contains the Object dictionary index and subindex.
bool download(const bool normal_transfer, const uint16_t index, const uint8_t subindex, const std::vector< uint8_t > &usrdata)
Downloads SDO data from the master to the slave (From PC to node).
eEMCY_STATUS getEmcyStatus() const
Returns the state of the EMCY state machine.
static std::map< uint16_t, std::string > m_eec_map
static const uint16_t ID_EMCY_MIN
bool getErrorInformation(uint16_t &eec, uint8_t &error_register, std::vector< uint8_t > &msef)
Returns the full error information.
ThreadStream & endl(ThreadStream &stream)
The EMCY class handles the spontaneously occurring Emergency (EMCY) messages, keeps track of a nodes ...
void printError(SDO &sdo, const uint8_t error_nr=1)
Prints a specific error from the error register 0x1003.
EMCY(const uint8_t node_id)
EMCY Constructs a new EMCY object. The error map will be filled separately.
static const uint16_t EMCY_ERROR_RESET_NO_ERROR
static std::string lookupErrorRegisterString(const uint8_t error_code)
static std::map< uint8_t, std::string > m_error_register_map
bool upload(const bool normal_transfer, const uint16_t index, const uint8_t subindex, std::vector< uint8_t > &uploaded_data)
Uploads data from a slave (node) to a master (PC).
eEMCY_STATUS
DS301 requests state error_free and error_occurred. This could be mapped into a bool, but maybe some other implementation needs more states, so we use an enum.
The SDO class represents Service Data Objects (SDO) that are used for slow access of the canOpen obje...
std::map< uint32_t, std::string > getErrorMapFromConfigFile(const std::string &filename, const std::string &category)
Creates an error map from a given INI file.
uint8_t m_error_register
register in which the error occured
std::string hexToString(const uint64_t num)
Converts a hexadecimal number into its string representation 0xXX.
boost::mutex m_data_buffer_mutex
std::vector< uint8_t > m_msef
manufacturer-specific error code
static void addErrorRegisterMap(const std::string &filename, const std::string &block_identifier)
Adds new information from an ini file to the error_register map.
#define LOGGING_ERROR_C(streamname, classname, arg)
virtual std::string lookupMSEFString() const