update HardWareManager

This commit is contained in:
linbo 2025-10-24 10:51:49 +08:00
parent f9521a72e7
commit 1a04ca2689
29 changed files with 68 additions and 588 deletions

View File

@ -90,7 +90,7 @@ target_link_libraries(cmvr_es PRIVATE
cmvr_es::utils
cmvr_es::service
cmvr_es::monitor
cmvr_es::hardware
cmvr_es::hardware_manager
cmvr_es::httpclient
cmvr_es::device::canbus
cmvr_es::device::ti5motor

View File

@ -6,15 +6,16 @@
#define CMVR_ES_CAN_GROUP_H
#include "motor_protocol/motorprotocolmanager.h"
namespace cmvr::device
namespace cmvr::hardware
{
class CanGroup
{
public:
explicit CanGroup(const XmlNode &cfg);
~CanGroup() = default;
private:
private:
std::string id_;
unsigned int channelId_;
bool enable_;

View File

@ -9,7 +9,7 @@
#include "rapidxml/rapidxml.hpp"
#include "can_group.h"
namespace cmvr::device
namespace cmvr::hardware
{
class CanManager
{

View File

@ -6,7 +6,7 @@
#define CMVR_ES_ABSTRACTMOTORPROTOCOL_H
#include "rapidxml/xml_parser.h"
namespace cmvr::device
namespace cmvr::hardware
{
class AbstractMotorProtocol
{

View File

@ -9,7 +9,7 @@
#include <memory>
#include "abstractmotorprotocol.h"
namespace cmvr::device
namespace cmvr::hardware
{
class MotorProtocolManager
{

View File

@ -7,7 +7,7 @@
#include "rapidxml/xml_parser.h"
#include "abstractmotorprotocol.h"
namespace cmvr::device{
namespace cmvr::hardware{
class Ti5MotorProtocol final : public AbstractMotorProtocol {
public:
explicit Ti5MotorProtocol(const XmlNode &cfg);

View File

@ -5,7 +5,7 @@
#ifndef CMVR_ES_SERIAL_MANAGER_H
#define CMVR_ES_SERIAL_MANAGER_H
#include "rapidxml/xml_parser.h"
namespace cmvr::device
namespace cmvr::hardware
{
class SerialManager
{

View File

@ -7,7 +7,7 @@
#include "rapidxml/xml_parser.h"
#include "hardware/can/can_manager.h"
namespace cmvr::device {
namespace cmvr::hardware {
class HardwareFactory {

View File

@ -9,7 +9,7 @@
#include <mutex>
#include "hardware_factory.h"
#include "hardware/can/can_manager.h"
namespace cmvr::device
namespace cmvr::hardware
{
class HardWareManager
{

View File

@ -11,7 +11,7 @@ find_package(ALSA REQUIRED)
add_library(cmvr::device::head_esp32 ALIAS head_esp32)
#
target_link_libraries(head_esp32 PRIVATE ALSA::ALSA )
target_link_libraries(head_esp32 PRIVATE ALSA::ALSA cmvr_es::hardware::serial)

View File

@ -2,7 +2,7 @@
#define CMVR_ES_BIOHEAD_ESP32_H
#include "devices/abstract_biohead.h"
#include "hardware/esp32_serial_port.h"
#include "../../../../include/hardware/serial/RS485/esp32_serial_port.h"
#include <vector>
#include <string>
#include <memory>

View File

@ -4,4 +4,4 @@ target_include_directories(rh56dftp_dexhand PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_library(cmvr_es::device::rh56dftp_dexhand ALIAS rh56dftp_dexhand)
target_link_libraries(rh56dftp_dexhand PRIVATE cmvr_es::hardware -lmodbus)
target_link_libraries(rh56dftp_dexhand PRIVATE cmvr_es::hardware_manager -lmodbus)

View File

@ -234,7 +234,32 @@ void RH56DFTPDexhand::init() {
LOG(INFO)<< "[RH56DFTPDexhand](init) sucess, id="<< id_;
}
std::vector<std::string> parse_error(unsigned char errorCode) {
std::vector<std::string> faults;
// 直接判断每一位是否为1
if (errorCode & (1 << 0)) { // Bit0: 堵转故障
faults.emplace_back("堵转故障");
}
if (errorCode & (1 << 1)) { // Bit1: 过温故障
faults.emplace_back("过温故障");
}
if (errorCode & (1 << 2)) { // Bit2: 过流故障
faults.emplace_back("过流故障");
}
if (errorCode & (1 << 3)) { // Bit3: 电机异常
faults.emplace_back("电机异常");
}
if (errorCode & (1 << 4)) { // Bit4: 通讯故障
faults.emplace_back("通讯故障");
}
return faults;
}
void RH56DFTPDexhand::updateState() {
//读取数据,初始化
std::vector<int> parsed_values;
@ -320,36 +345,6 @@ void RH56DFTPDexhand::updateState() {
}
}
}
void printPinkySensorData(const HandTactileSensors& sensors) {
// 打印小拇指指端数据
std::cout << "=== 小拇指指端数据 (" << sensors.pinky.tip.rows << "x" << sensors.pinky.tip.cols << ") ===\n";
for (const auto& row : sensors.pinky.tip.data) {
for (TactilePoint value : row) {
std::cout << std::setw(5) << value; // 每个值占5个字符宽度
}
std::cout << "\n";
}
std::cout << "\n";
// 打印小拇指指尖数据
std::cout << "=== 小拇指指尖数据 (" << sensors.pinky.finger.rows << "x" << sensors.pinky.finger.cols << ") ===\n";
for (const auto& row : sensors.pinky.finger.data) {
for (TactilePoint value : row) {
std::cout << std::setw(5) << value;
}
std::cout << "\n";
}
std::cout << "\n";
// 打印小拇指指腹数据
std::cout << "=== 小拇指指腹数据 (" << sensors.pinky.pad.rows << "x" << sensors.pinky.pad.cols << ") ===\n";
for (const auto& row : sensors.pinky.pad.data) {
for (TactilePoint value : row) {
std::cout << std::setw(5) << value;
}
std::cout << "\n";
}
}
void RH56DFTPDexhand::updateSensorData() {
//触觉传感器数据。

View File

@ -11,9 +11,8 @@
#include <condition_variable>
#include <modbus/modbus.h>
#include <boost/lockfree/spsc_queue.hpp>
#include "../../../../include/utils/base/os.h"
#include "utils/base/os.h"
#include "devices/abstract_dexhand.h"
#include "hardware/serial_interface.h"
namespace cmvr::device {
@ -67,8 +66,6 @@ namespace cmvr::device {
int default_force_;//上电的力控阈值
int default_speed_;//上电的自由角转动速度
std::shared_ptr<serial_interface> serial_;
std::string ip_address_;
int port_;
std::shared_ptr<ModbusController> controller_;

View File

@ -1,18 +1,3 @@
add_subdirectory(can)
add_subdirectory(serial)
add_library(hardware SHARED
esp32_serial_port.cpp
serial_interface.cpp
)
target_include_directories(hardware PUBLIC
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(hardware PRIVATE
cmvr_es::can
cmvr_es::serial
)
add_library(cmvr_es::hardware ALIAS hardware)

View File

@ -11,4 +11,4 @@ target_link_libraries(can PRIVATE
cmvr_es::motor_protocol
)
add_library(cmvr_es::can ALIAS can)
add_library(cmvr_es::hardware::can ALIAS can)

View File

@ -5,7 +5,7 @@
#include "hardware/can/can_group.h"
#include <glog/logging.h>
using namespace std;
using namespace cmvr::device;
using namespace cmvr::hardware;
CanGroup::CanGroup(const XmlNode &cfg)
{

View File

@ -6,7 +6,7 @@
#include <glog/logging.h>
using namespace std;
using namespace cmvr::device;
using namespace cmvr::hardware;
CanManager::CanManager(const XmlNode& cfg)
{

View File

@ -7,7 +7,7 @@
#include <glog/logging.h>
using namespace std;
using namespace cmvr::device;
using namespace cmvr::hardware;

View File

@ -3,7 +3,7 @@
//
#include "hardware/can/motor_protocol/ti5motorprotocol.h"
using namespace cmvr::device;
using namespace cmvr::hardware;
Ti5MotorProtocol::Ti5MotorProtocol(const XmlNode &cfg):AbstractMotorProtocol(cfg)
{

View File

@ -1,3 +1,7 @@
#add_subdirectory(IO)
add_subdirectory(RS485)
add_library(serial
serial_manager.cpp
)
@ -5,7 +9,7 @@ add_library(serial
target_include_directories(serial PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(serial PRIVATE
protobuf::libprotobuf
cmvr_es::hardware::rs485
)
add_library(cmvr_es::serial ALIAS serial)
add_library(cmvr_es::hardware::serial ALIAS serial)

View File

@ -0,0 +1,9 @@
add_library(rs485 SHARED
esp32_serial_port.cpp
)
target_include_directories(rs485 PUBLIC
${PROJECT_SOURCE_DIR}/include
)
add_library(cmvr_es::hardware::rs485 ALIAS rs485)

View File

@ -1,5 +1,5 @@
// esp32_serial_port.cpp
#include "hardware/esp32_serial_port.h"
#include "hardware/serial/RS485/esp32_serial_port.h"
#include <iostream>
#include <fcntl.h>
#include <unistd.h>

View File

@ -5,7 +5,7 @@
#include "hardware/serial/serial_manager.h"
using namespace std;
using namespace cmvr::device;
using namespace cmvr::hardware;
SerialManager::SerialManager(const XmlNode &cfg)
{

View File

@ -1,512 +0,0 @@
//
// Created by xtkuang on 2025/5/6.
//
#include "hardware/serial_interface.h"
#include <iostream>
#include <bitset>
#include <vector>
#include <string>
#include <iomanip>
#include <sstream>
#include <random>
#include <chrono>
#include <glog/logging.h>
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
using namespace boost::asio;
// 地址转换和二进制转十六进制函数
std::string convertAddressToBinary_read(int address_dec, const std::string& id_value) {
std::string address_bin = std::bitset<32>(address_dec).to_string();
size_t first_one = address_bin.find('1');
if (first_one != std::string::npos) {
address_bin = address_bin.substr(first_one);
} else {
address_bin = "0";
}
std::string formatted_output = "0000000" + address_bin + "000000000000" + id_value;
return formatted_output;
}
std::string convertAddressToBinary_write(int address_dec, const std::string& id_value) {
std::string address_bin = std::bitset<32>(address_dec).to_string();
size_t first_one = address_bin.find('1');
if (first_one != std::string::npos) {
address_bin = address_bin.substr(first_one);
} else {
address_bin = "0";
}
std::string formatted_output = "0000010" + address_bin + "000000000000" + id_value;
return formatted_output;
}
std::string binaryToHex(const std::string& binary_string) {
unsigned long decimal_value = std::stoul(binary_string, nullptr, 2);
std::stringstream ss;
ss << std::hex << std::uppercase << decimal_value;
return ss.str();
}
// 处理十六进制数据的函数
std::vector<unsigned char> processHexData(const std::string& hex_data) {
std::string padded_hex = hex_data;
if (padded_hex.length() < 8) {
padded_hex = std::string(8 - padded_hex.length(), '0') + padded_hex;
}
std::vector<unsigned char> processed_data;
for (size_t i = padded_hex.length(); i > 0; i -= 2) {
std::string byte_str = padded_hex.substr(i - 2, 2);
unsigned char byte_value = static_cast<unsigned char>(std::stoi(byte_str, nullptr, 16));
processed_data.push_back(byte_value);
}
return processed_data;
}
namespace cmvr {
// 构造函数,初始化串口参数
serial_interface::serial_interface(const std::string& port, unsigned int baudrate, CommunicationMode mode) : io(), comm_mode(mode),timer(io), timeout(false) {
try {
serial = std::make_shared<serial_port>(io, port);
serial->set_option(serial_port_base::baud_rate(baudrate));
serial->set_option(serial_port_base::character_size(8)); // 数据位
serial->set_option(serial_port_base::parity(serial_port_base::parity::none)); // 无校验位
serial->set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one)); // 1个停止位
is_initialized = true;
}
catch (const std::exception& e) {
is_initialized = false;
LOG(ERROR) << "[serial_interface] ([serial_interface]): Failed to init serialport: " << e.what();
}
}
bool serial_interface::isInitialized() {
return is_initialized;
}
void serial_interface::on_timeout(const boost::system::error_code& ec) {
if (!ec) {
timeout = true;
serial->cancel();
}
}
void serial_interface::on_read_complete(const boost::system::error_code& ec, size_t bytes_transferred, boost::system::error_code* out_ec, size_t* out_bytes_transferred) {
*out_ec = ec;
*out_bytes_transferred = bytes_transferred;
timer.cancel();
}
// 向串口写入数据
void serial_interface::write(const std::vector<unsigned char>& data) {
if (comm_mode == CommunicationMode::RS485) {
boost::asio::write(*serial, buffer(data));
} else if (comm_mode == CommunicationMode::CAN) {
// CAN模式下的写入逻辑这里简化为和RS485相同可根据实际情况修改
boost::asio::write(*serial, buffer(data));
}
}
// 从串口读取指定长度的数据
std::vector<unsigned char> serial_interface::read(size_t length) {
std::vector<unsigned char> buffer(length);
if (comm_mode == CommunicationMode::RS485) {
boost::asio::read(*serial, boost::asio::buffer(buffer.data(), length));
} else if (comm_mode == CommunicationMode::CAN) {
timeout = false;
int timeout_ms = 1000;
timer.expires_after(std::chrono::milliseconds(timeout_ms));
timer.async_wait(boost::bind(&serial_interface::on_timeout, this, boost::asio::placeholders::error));
boost::system::error_code ec;
size_t bytes_transferred = 0;
serial->async_read_some(boost::asio::buffer(buffer),
boost::bind(&serial_interface::on_read_complete, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, &ec, &bytes_transferred));
io.run();
io.reset();
if (timeout) {
throw std::runtime_error("串口读取超时");
}
if (ec) {
throw boost::system::system_error(ec);
}
buffer.resize(bytes_transferred);
}
return buffer;
}
CommunicationMode serial_interface::getCommunicationMode()
{
return comm_mode;
}
// 根据寄存器名称获取地址
int getAddressByName(const std::string& reg_name) {
for (const auto& reg : regdict) {
if (reg.name == reg_name) {
return reg.address; // 返回匹配的地址
}
}
return -1; // 未找到寄存器名称,返回 -1
}
// 写寄存器函数
void write_register(serial_interface& serial, int address_decimal, const std::string& id_value, const std::vector<int>& values_to_write) {
if (values_to_write.size() > 6) {
std::cerr << "超过允许的值数量最多只能写入6个值" << std::endl;
return;
}
if (serial.getCommunicationMode() == CommunicationMode::RS485) {
// RS485模式下的写寄存器逻辑
std::vector<unsigned char> send_buffer;
send_buffer.push_back(0xEB);
send_buffer.push_back(0x90);
send_buffer.push_back(static_cast<unsigned char>(std::stoi(id_value))); // 将 ID 转换为 unsigned char
size_t num_values = values_to_write.size();
auto data_length = static_cast<unsigned char>(num_values * 2 + 3);
send_buffer.push_back(data_length);
send_buffer.push_back(0x12); // 写寄存器命令
send_buffer.push_back(static_cast<unsigned char>(address_decimal & 0xFF)); // 地址低八位
send_buffer.push_back(static_cast<unsigned char>((address_decimal >> 8) & 0xFF)); // 地址高八位
// 将要写入的值添加到数据包中
for (int value : values_to_write) {
send_buffer.push_back(static_cast<unsigned char>(value & 0xFF)); // 写入值低八位
send_buffer.push_back(static_cast<unsigned char>((value >> 8) & 0xFF)); // 写入值高八位
}
// 计算校验和,从 ID 部分开始
unsigned char checksum = 0;
for (size_t k = 2; k < send_buffer.size(); ++k) {
checksum += send_buffer[k];
}
send_buffer.push_back(checksum & 0xFF); // 添加校验和
// // 输出发送的数据
// std::cout << "发送的写入数据: ";
// for (auto byte : send_buffer) {
// std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
// }
// std::cout << std::endl;
// 写入数据
serial.write(send_buffer);
// 读取并丢弃写入后的响应
try {
std::vector<unsigned char> discard_buffer = serial.read(9);
std::cout << "写操作后的响应数据已丢弃,字节数: " << discard_buffer.size() << std::endl;
} catch (const std::exception& e) {
std::cerr << "写操作后的响应数据读取失败: " << e.what() << std::endl;
}
}
else if (serial.getCommunicationMode() == CommunicationMode::CAN) {
// CAN模式下的写寄存器逻辑
std::vector<int> first_chunk(values_to_write.begin(), values_to_write.begin() + std::min(4, (int)values_to_write.size()));
std::vector<int> second_chunk(values_to_write.begin() + first_chunk.size(), values_to_write.end());
// 构造并发送第一段数据
auto construct_and_send = [&](const std::vector<int>& chunk, int addr) {
// 转换地址为二进制->十六进制
std::string result_bin = convertAddressToBinary_write(addr, id_value);
std::string result_hex = binaryToHex(result_bin);
std::vector<unsigned char> processed_data = processHexData(result_hex);
// 构造数据帧
std::vector<unsigned char> send_buffer;
send_buffer.push_back(0xAA);
send_buffer.push_back(0xAA);
send_buffer.insert(send_buffer.end(), processed_data.begin(), processed_data.end());
// 写入值
for (int value : chunk) {
send_buffer.push_back(value & 0xFF); // 低八位
send_buffer.push_back((value >> 8) & 0xFF); // 高八位
}
while (send_buffer.size() < 14) {
send_buffer.push_back(0x00);
}
// 添加固定字节
send_buffer.push_back(chunk.size() * 2); // 数据长度
send_buffer.push_back(0x00);
send_buffer.push_back(0x01);
send_buffer.push_back(0x00);
// 计算校验和
unsigned char checksum = 0;
for (size_t k = 2; k < send_buffer.size(); ++k) {
checksum += send_buffer[k];
}
send_buffer.push_back(checksum & 0xFF);
send_buffer.push_back(0x55);
send_buffer.push_back(0x55);
// 打印并发送
// std::cout << "发送的完整数据: ";
// for (auto byte : send_buffer) {
// std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
// }
// std::cout << std::endl;
serial.write(send_buffer);
// 读掉响应数据,不处理
try {
std::vector<unsigned char> discard_buffer = serial.read(32);
} catch (const std::exception& e) {
std::cerr << "写操作后的响应数据读取失败: " << e.what() << std::endl;
}
};
// 发送第一段
construct_and_send(first_chunk, address_decimal);
// 如果有第二段值,发送第二段
if (!second_chunk.empty()) {
construct_and_send(second_chunk, address_decimal + 8); // 地址后移 8
}
}
}
// 读寄存器函数
std::vector<unsigned char> read_register(serial_interface& serial, int address_decimal, const std::string& id_value,
size_t register_length, size_t length_to_read) {
std::vector<unsigned char> send_buffer;
if (serial.getCommunicationMode() == CommunicationMode::RS485) {
// RS485模式下的读寄存器逻辑
send_buffer.push_back(0xEB);
send_buffer.push_back(0x90);
send_buffer.push_back(static_cast<unsigned char>(std::stoi(id_value))); // 将 ID 转换为 unsigned char
send_buffer.push_back(0x04);
send_buffer.push_back(0x11);
send_buffer.push_back(static_cast<unsigned char>(address_decimal & 0xFF)); // 地址低八位
send_buffer.push_back(static_cast<unsigned char>((address_decimal >> 8) & 0xFF)); // 地址高八位
send_buffer.push_back(register_length); // 读取寄存器长度
// 计算校验和
unsigned char checksum = 0;
for (size_t k = 2; k < send_buffer.size(); ++k) {
checksum += send_buffer[k];
}
send_buffer.push_back(checksum & 0xFF);
// std::cout << "发送的完整数据: ";
// for (auto byte : send_buffer) {
// std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
// }
// std::cout << std::endl;
serial.write(send_buffer); // 写入串口
// 读取响应数据
std::vector<unsigned char> received_data = serial.read(length_to_read);
// // 打印接收到的原始响应数据
// std::cout << "接收到的原始响应数据: ";
// for (auto byte : received_data) {
// std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)byte << " ";
// }
// std::cout << std::endl;
return received_data;
}
return send_buffer;
}
std::vector<int> read_register_can(serial_interface& serial, int address_decimal, const std::string& id_value, size_t register_length, size_t length_to_read, bool parse_as_short) {
std::vector<int> parsed_values;
size_t bytes_read = 0;
while (bytes_read < register_length) {
std::vector<unsigned char> send_buffer;
// 生成地址相关数据
std::string result_bin = convertAddressToBinary_read(address_decimal, id_value);
std::string result_hex = binaryToHex(result_bin);
std::vector<unsigned char> processed_data = processHexData(result_hex);
// 动态计算数据长度控制字段(关键调整)
size_t current_remaining = register_length - bytes_read;
size_t data_length = (parse_as_short)
? std::min(8UL, (current_remaining + 1) & ~1UL) // 按short对齐到偶数
: std::min(8UL, current_remaining); // 按byte无需对齐
// 构建发送缓冲区
send_buffer.push_back(0xAA);
send_buffer.push_back(0xAA);
send_buffer.insert(send_buffer.end(), processed_data.begin(), processed_data.end());
send_buffer.push_back(static_cast<unsigned char>(data_length)); // 动态数据长度
send_buffer.insert(send_buffer.end(), 7, 0x00);
send_buffer.push_back(0x01);
send_buffer.push_back(0x00);
send_buffer.push_back(0x01);
send_buffer.push_back(0x00);
// 计算校验和
unsigned char checksum = 0;
for (size_t k = 2; k < send_buffer.size(); ++k) {
checksum += send_buffer[k];
}
send_buffer.push_back(checksum & 0xFF);
send_buffer.push_back(0x55);
send_buffer.push_back(0x55);
// 发送并接收数据
serial.write(send_buffer);
std::vector<unsigned char> received_data = serial.read(length_to_read);
// 定位有效数据起始位置
size_t start_pos = 0;
while (start_pos < received_data.size() && received_data[start_pos] != 0xAA) {
start_pos++;
}
// 根据解析类型处理数据
if (parse_as_short) {
size_t shorts_to_read = data_length / 2;
for (size_t j = start_pos + 6; j < start_pos + 6 + data_length; j += 2) {
if (j + 1 < received_data.size()) {
int value = (received_data[j + 1] << 8) | received_data[j];
if (value > 6000) value = 0;
parsed_values.push_back(value);
bytes_read += 2;
}
}
} else {
for (size_t j = start_pos + 6; j < start_pos + 6 + data_length; j++) {
if (j < received_data.size()) {
parsed_values.push_back(received_data[j]);
bytes_read++;
}
}
}
address_decimal += static_cast<int>(data_length); // 地址后移8字节
}
return parsed_values;
}
std::vector<unsigned char> read_register_can_single(serial_interface& serial, int address_decimal, const std::string& id_value, size_t register_length, size_t length_to_read) {
std::vector<unsigned char> all_parsed_values;
size_t bytes_read = 0;
while (bytes_read < register_length) {
std::vector<unsigned char> send_buffer;
std::vector<unsigned char> parsed_values;
std::string result_bin = convertAddressToBinary_read(address_decimal, id_value);
std::string result_hex = binaryToHex(result_bin);
std::vector<unsigned char> processed_data = processHexData(result_hex);
send_buffer.push_back(0xAA);
send_buffer.push_back(0xAA);
send_buffer.insert(send_buffer.end(), processed_data.begin(), processed_data.end());
send_buffer.push_back(0x08); // 数据长度控制
send_buffer.insert(send_buffer.end(), 7, 0x00);
send_buffer.push_back(0x01);
send_buffer.push_back(0x00);
send_buffer.push_back(0x01);
send_buffer.push_back(0x00);
unsigned char checksum = 0;
for (size_t k = 2; k < send_buffer.size(); ++k) {
checksum += send_buffer[k];
}
send_buffer.push_back(checksum & 0xFF); // 添加校验和
send_buffer.push_back(0x55);
send_buffer.push_back(0x55);
serial.write(send_buffer);
// 读取响应数据
std::vector<unsigned char> received_data = serial.read(length_to_read);
// 找到第一个 0xAA 的位置
size_t start_pos = 0;
while (start_pos < received_data.size() && received_data[start_pos] != 0xAA) {
start_pos++;
}
// 从第一个 0xAA 开始解析数据,每次最多读取 8 字节
size_t bytes_to_read = std::min(8UL, register_length - bytes_read);
for (size_t j = start_pos + 6; j < start_pos + 6 + bytes_to_read; j++) {
if (j < received_data.size()) {
parsed_values.push_back(received_data[j]);
}
}
all_parsed_values.insert(all_parsed_values.end(), parsed_values.begin(), parsed_values.end());
bytes_read += parsed_values.size();
address_decimal += 8; // 地址后移 8 字节
}
return all_parsed_values;
}
std::vector<int> parse_register(const std::vector<unsigned char>& data,int start_byte, size_t register_length,int per_byte){
std::vector<int> parsed_values;
for (size_t j = 7; j < register_length + 7; j += 2) {
if (j + 1 < data.size()) {
int value = 0;
//根据数据位数获取数据
if (per_byte == 1) {
value = data[j];
}
else if (per_byte == 2) {
value = (data[j + 1] << 8) | data[j];
}
if (value > 6000) {
value = 0;
}
parsed_values.push_back(value);
}
}
return parsed_values;
}
std::vector<std::string> parse_error(unsigned char errorCode) {
std::vector<std::string> faults;
// 直接判断每一位是否为1
if (errorCode & (1 << 0)) { // Bit0: 堵转故障
faults.emplace_back("堵转故障");
}
if (errorCode & (1 << 1)) { // Bit1: 过温故障
faults.emplace_back("过温故障");
}
if (errorCode & (1 << 2)) { // Bit2: 过流故障
faults.emplace_back("过流故障");
}
if (errorCode & (1 << 3)) { // Bit3: 电机异常
faults.emplace_back("电机异常");
}
if (errorCode & (1 << 4)) { // Bit4: 通讯故障
faults.emplace_back("通讯故障");
}
return faults;
}
}

View File

@ -1,12 +1,13 @@
add_library(hardware_manager SHARED
hardware_factory.cpp
hardware_manager.cpp
../hardware/can/can_manager.cpp
../hardware/serial/serial_manager.cpp
)
target_include_directories(hardware_manager PUBLIC
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(hardware_manager PRIVATE
cmvr_es::hardware::can
cmvr_es::hardware::serial
)
add_library(cmvr_es::hardware_manager ALIAS hardware_manager)

View File

@ -6,7 +6,7 @@
#include <glog/logging.h>
using namespace std;
using namespace cmvr::device;
using namespace cmvr::hardware;
template std::shared_ptr<CanManager> HardwareFactory::create<CanManager>(const XmlNode&);

View File

@ -4,7 +4,7 @@
#include "hardware_manager/hardware_manager.h"
using namespace std;
using namespace cmvr::device;
using namespace cmvr::hardware;
std::shared_ptr<HardWareManager> HardWareManager::instance_ = nullptr;
HardWareManager::HardWareManager(const XmlNode& cfg) {