cmvr-es/cmvr-es/devices/canbus/canopen/sdo_response_protocol.h

98 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by lgv on 2025/7/17.
//
#pragma once
#include "canbus/can_comm/protocol_data.h"
#include "cmvr/msgs/robot_detail.pb.h"
#include "sdo_response_protocol.h"
#include "common/base/logging/logger.h"
namespace cmvr {
namespace device {
template<typename SensorType>
class SdoResponseProtocol : public ProtocolData<SensorType> {
public:
static constexpr uint32_t BASE_ID = 0x580;
static uint32_t ID(uint8_t node_id) {
return BASE_ID + node_id;
}
uint32_t ID() const{
return BASE_ID + node_id_;
}
explicit SdoResponseProtocol(uint8_t node_id) : node_id_(node_id), message_id_(BASE_ID + node_id) {
}
void Parse(const std::uint8_t *bytes, int32_t length, SensorType *sensor_data) const override;
virtual void ParseSdoData(const msgs::SdoFrame &sdo_response, SensorType *sensor_data) const {}
void UpdateData(uint8_t *data) override {}
protected:
uint8_t node_id_;
uint32_t message_id_;
mutable msgs::SdoFrame sdo_response_; // 成员变量
};
template<typename SensorType>
void SdoResponseProtocol<SensorType>::Parse(const std::uint8_t *bytes, int32_t length,SensorType *sensor_data) const {
if (length < 8) {
CMVR_LOG(WARNING) << "MotorSdoResponseProtocol: data length too short: " << length;
return;
}
// 解析 command 字段第0字节
auto command = static_cast<msgs::CommandSpecifier>(bytes[0]);
// 解析 index字节1和字节2低字节优先
const uint32_t index = bytes[1] + (bytes[2] << 8);
// 解析 subindex字节3
const uint32_t subindex = bytes[3];
// 根据 command 解析 data字节4~7
uint32_t data = 0;
switch (command) {
case msgs::CS_READ_RESPONSE_ONE_BYTE:
data = bytes[4];
break;
case msgs::CS_READ_RESPONSE_TWO_BYTES:
data = bytes[5] + (bytes[4] << 8);
break;
case msgs::CS_READ_RESPONSE_THREE_BYTES:
data = bytes[4] + (bytes[5] << 8) + (bytes[6] << 16);
(static_cast<uint32_t>(bytes[5]) << 8) |
(static_cast<uint32_t>(bytes[6]) << 16);
break;
case msgs::CS_READ_RESPONSE_FOUR_BYTES:
data = bytes[4] + (bytes[5] << 8) + (bytes[6] << 16) + (bytes[7] << 24);
break;
case msgs::CS_WRITE_SUCCESS_RESPONSE:
data = 0;
break;
case msgs::CS_EXCEPTION_RESPONSE:
break;
default:
CMVR_LOG(WARNING) << "Unknown command specifier: " << std::hex << static_cast<int>(command);
data = 0;
break;
}
sdo_response_.set_node_id(node_id_);
sdo_response_.set_cs(command);
sdo_response_.set_index(index);
sdo_response_.set_sub_index(subindex);
sdo_response_.set_data(data);
// 子类实现的扩展解析data逻辑
ParseSdoData(sdo_response_, sensor_data);
}
}
}