From 1a04ca2689adf08ce394777847b9a1e0fa9cc521 Mon Sep 17 00:00:00 2001 From: linbo <1034003879@qq.com> Date: Fri, 24 Oct 2025 10:51:49 +0800 Subject: [PATCH] update HardWareManager --- CMakeLists.txt | 2 +- include/hardware/can/can_group.h | 5 +- include/hardware/can/can_manager.h | 2 +- .../motor_protocol/abstractmotorprotocol.h | 2 +- .../can/motor_protocol/motorprotocolmanager.h | 2 +- .../can/motor_protocol/ti5motorprotocol.h | 2 +- .../{ => serial/RS485}/esp32_serial_port.h | 0 include/hardware/serial/serial_manager.h | 2 +- include/hardware_manager/hardware_factory.h | 2 +- include/hardware_manager/hardware_manager.h | 2 +- .../biohead/biohead_esp32/CMakeLists.txt | 2 +- .../biohead/biohead_esp32/biohead_esp32.h | 2 +- .../dexhand/rh56dftp_dexhand/CMakeLists.txt | 2 +- .../rh56dftp_dexhand/rh56dftp_dexhand.cpp | 55 +- .../rh56dftp_dexhand/rh56dftp_dexhand.h | 5 +- src/hardware/CMakeLists.txt | 15 - src/hardware/can/CMakeLists.txt | 2 +- src/hardware/can/can_group.cpp | 2 +- src/hardware/can/can_manager.cpp | 2 +- .../motor_protocol/motorprotocolmanager.cpp | 2 +- .../can/motor_protocol/ti5motorprotocol.cpp | 2 +- src/hardware/serial/CMakeLists.txt | 8 +- src/hardware/serial/RS485/CMakeLists.txt | 9 + .../{ => serial/RS485}/esp32_serial_port.cpp | 2 +- src/hardware/serial/serial_manager.cpp | 2 +- src/hardware/serial_interface.cpp | 512 ------------------ src/hardware_manager/CMakeLists.txt | 7 +- src/hardware_manager/hardware_factory.cpp | 2 +- src/hardware_manager/hardware_manager.cpp | 2 +- 29 files changed, 68 insertions(+), 588 deletions(-) rename include/hardware/{ => serial/RS485}/esp32_serial_port.h (100%) create mode 100644 src/hardware/serial/RS485/CMakeLists.txt rename src/hardware/{ => serial/RS485}/esp32_serial_port.cpp (98%) delete mode 100644 src/hardware/serial_interface.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index aa276be7..5fc555a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/hardware/can/can_group.h b/include/hardware/can/can_group.h index 9afef933..a6671caf 100644 --- a/include/hardware/can/can_group.h +++ b/include/hardware/can/can_group.h @@ -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_; diff --git a/include/hardware/can/can_manager.h b/include/hardware/can/can_manager.h index 424fdf8e..2d1573cb 100644 --- a/include/hardware/can/can_manager.h +++ b/include/hardware/can/can_manager.h @@ -9,7 +9,7 @@ #include "rapidxml/rapidxml.hpp" #include "can_group.h" -namespace cmvr::device +namespace cmvr::hardware { class CanManager { diff --git a/include/hardware/can/motor_protocol/abstractmotorprotocol.h b/include/hardware/can/motor_protocol/abstractmotorprotocol.h index 0c4c19a0..81e88af8 100644 --- a/include/hardware/can/motor_protocol/abstractmotorprotocol.h +++ b/include/hardware/can/motor_protocol/abstractmotorprotocol.h @@ -6,7 +6,7 @@ #define CMVR_ES_ABSTRACTMOTORPROTOCOL_H #include "rapidxml/xml_parser.h" -namespace cmvr::device +namespace cmvr::hardware { class AbstractMotorProtocol { diff --git a/include/hardware/can/motor_protocol/motorprotocolmanager.h b/include/hardware/can/motor_protocol/motorprotocolmanager.h index c5de6437..e72efe10 100644 --- a/include/hardware/can/motor_protocol/motorprotocolmanager.h +++ b/include/hardware/can/motor_protocol/motorprotocolmanager.h @@ -9,7 +9,7 @@ #include #include "abstractmotorprotocol.h" -namespace cmvr::device +namespace cmvr::hardware { class MotorProtocolManager { diff --git a/include/hardware/can/motor_protocol/ti5motorprotocol.h b/include/hardware/can/motor_protocol/ti5motorprotocol.h index 19bc164b..c797a04f 100644 --- a/include/hardware/can/motor_protocol/ti5motorprotocol.h +++ b/include/hardware/can/motor_protocol/ti5motorprotocol.h @@ -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); diff --git a/include/hardware/esp32_serial_port.h b/include/hardware/serial/RS485/esp32_serial_port.h similarity index 100% rename from include/hardware/esp32_serial_port.h rename to include/hardware/serial/RS485/esp32_serial_port.h diff --git a/include/hardware/serial/serial_manager.h b/include/hardware/serial/serial_manager.h index 08fea033..36ebafca 100644 --- a/include/hardware/serial/serial_manager.h +++ b/include/hardware/serial/serial_manager.h @@ -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 { diff --git a/include/hardware_manager/hardware_factory.h b/include/hardware_manager/hardware_factory.h index 0ae04f79..c5d96997 100644 --- a/include/hardware_manager/hardware_factory.h +++ b/include/hardware_manager/hardware_factory.h @@ -7,7 +7,7 @@ #include "rapidxml/xml_parser.h" #include "hardware/can/can_manager.h" -namespace cmvr::device { +namespace cmvr::hardware { class HardwareFactory { diff --git a/include/hardware_manager/hardware_manager.h b/include/hardware_manager/hardware_manager.h index be5d159e..606e5343 100644 --- a/include/hardware_manager/hardware_manager.h +++ b/include/hardware_manager/hardware_manager.h @@ -9,7 +9,7 @@ #include #include "hardware_factory.h" #include "hardware/can/can_manager.h" -namespace cmvr::device +namespace cmvr::hardware { class HardWareManager { diff --git a/src/devices/biohead/biohead_esp32/CMakeLists.txt b/src/devices/biohead/biohead_esp32/CMakeLists.txt index a5a39bd9..f7e5dbc3 100644 --- a/src/devices/biohead/biohead_esp32/CMakeLists.txt +++ b/src/devices/biohead/biohead_esp32/CMakeLists.txt @@ -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) diff --git a/src/devices/biohead/biohead_esp32/biohead_esp32.h b/src/devices/biohead/biohead_esp32/biohead_esp32.h index 892e1f0a..014e40f1 100644 --- a/src/devices/biohead/biohead_esp32/biohead_esp32.h +++ b/src/devices/biohead/biohead_esp32/biohead_esp32.h @@ -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 #include #include diff --git a/src/devices/dexhand/rh56dftp_dexhand/CMakeLists.txt b/src/devices/dexhand/rh56dftp_dexhand/CMakeLists.txt index 966d1bcb..a6487dea 100644 --- a/src/devices/dexhand/rh56dftp_dexhand/CMakeLists.txt +++ b/src/devices/dexhand/rh56dftp_dexhand/CMakeLists.txt @@ -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) \ No newline at end of file +target_link_libraries(rh56dftp_dexhand PRIVATE cmvr_es::hardware_manager -lmodbus) \ No newline at end of file diff --git a/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.cpp b/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.cpp index 62479f6a..4b4ca427 100644 --- a/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.cpp +++ b/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.cpp @@ -234,7 +234,32 @@ void RH56DFTPDexhand::init() { LOG(INFO)<< "[RH56DFTPDexhand](init) sucess, id="<< id_; } +std::vector parse_error(unsigned char errorCode) { + std::vector 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 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() { //触觉传感器数据。 diff --git a/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.h b/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.h index da1b34ea..6a914be9 100644 --- a/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.h +++ b/src/devices/dexhand/rh56dftp_dexhand/rh56dftp_dexhand.h @@ -11,9 +11,8 @@ #include #include #include -#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_; - std::string ip_address_; int port_; std::shared_ptr controller_; diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt index 1a5cde23..9152bd52 100644 --- a/src/hardware/CMakeLists.txt +++ b/src/hardware/CMakeLists.txt @@ -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) - diff --git a/src/hardware/can/CMakeLists.txt b/src/hardware/can/CMakeLists.txt index 73132d56..31f9b47f 100644 --- a/src/hardware/can/CMakeLists.txt +++ b/src/hardware/can/CMakeLists.txt @@ -11,4 +11,4 @@ target_link_libraries(can PRIVATE cmvr_es::motor_protocol ) -add_library(cmvr_es::can ALIAS can) \ No newline at end of file +add_library(cmvr_es::hardware::can ALIAS can) \ No newline at end of file diff --git a/src/hardware/can/can_group.cpp b/src/hardware/can/can_group.cpp index b80c48a4..88ed417a 100644 --- a/src/hardware/can/can_group.cpp +++ b/src/hardware/can/can_group.cpp @@ -5,7 +5,7 @@ #include "hardware/can/can_group.h" #include using namespace std; -using namespace cmvr::device; +using namespace cmvr::hardware; CanGroup::CanGroup(const XmlNode &cfg) { diff --git a/src/hardware/can/can_manager.cpp b/src/hardware/can/can_manager.cpp index 8a22318e..d218d9c1 100644 --- a/src/hardware/can/can_manager.cpp +++ b/src/hardware/can/can_manager.cpp @@ -6,7 +6,7 @@ #include using namespace std; -using namespace cmvr::device; +using namespace cmvr::hardware; CanManager::CanManager(const XmlNode& cfg) { diff --git a/src/hardware/can/motor_protocol/motorprotocolmanager.cpp b/src/hardware/can/motor_protocol/motorprotocolmanager.cpp index 6bc306e5..2c1b9f04 100644 --- a/src/hardware/can/motor_protocol/motorprotocolmanager.cpp +++ b/src/hardware/can/motor_protocol/motorprotocolmanager.cpp @@ -7,7 +7,7 @@ #include using namespace std; -using namespace cmvr::device; +using namespace cmvr::hardware; diff --git a/src/hardware/can/motor_protocol/ti5motorprotocol.cpp b/src/hardware/can/motor_protocol/ti5motorprotocol.cpp index e2d78849..54e1f5a9 100644 --- a/src/hardware/can/motor_protocol/ti5motorprotocol.cpp +++ b/src/hardware/can/motor_protocol/ti5motorprotocol.cpp @@ -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) { diff --git a/src/hardware/serial/CMakeLists.txt b/src/hardware/serial/CMakeLists.txt index 23789efb..e23a6f08 100644 --- a/src/hardware/serial/CMakeLists.txt +++ b/src/hardware/serial/CMakeLists.txt @@ -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) \ No newline at end of file +add_library(cmvr_es::hardware::serial ALIAS serial) \ No newline at end of file diff --git a/src/hardware/serial/RS485/CMakeLists.txt b/src/hardware/serial/RS485/CMakeLists.txt new file mode 100644 index 00000000..8e960b4e --- /dev/null +++ b/src/hardware/serial/RS485/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/src/hardware/esp32_serial_port.cpp b/src/hardware/serial/RS485/esp32_serial_port.cpp similarity index 98% rename from src/hardware/esp32_serial_port.cpp rename to src/hardware/serial/RS485/esp32_serial_port.cpp index 3627a8e8..1438f587 100644 --- a/src/hardware/esp32_serial_port.cpp +++ b/src/hardware/serial/RS485/esp32_serial_port.cpp @@ -1,5 +1,5 @@ // esp32_serial_port.cpp -#include "hardware/esp32_serial_port.h" +#include "hardware/serial/RS485/esp32_serial_port.h" #include #include #include diff --git a/src/hardware/serial/serial_manager.cpp b/src/hardware/serial/serial_manager.cpp index 0cd140de..1466250c 100644 --- a/src/hardware/serial/serial_manager.cpp +++ b/src/hardware/serial/serial_manager.cpp @@ -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) { diff --git a/src/hardware/serial_interface.cpp b/src/hardware/serial_interface.cpp deleted file mode 100644 index 14fe6979..00000000 --- a/src/hardware/serial_interface.cpp +++ /dev/null @@ -1,512 +0,0 @@ -// -// Created by xtkuang on 2025/5/6. -// - -#include "hardware/serial_interface.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 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 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(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(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& 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 serial_interface::read(size_t length) { - std::vector 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& values_to_write) { - if (values_to_write.size() > 6) { - std::cerr << "超过允许的值数量,最多只能写入6个值!" << std::endl; - return; - } - - if (serial.getCommunicationMode() == CommunicationMode::RS485) { - // RS485模式下的写寄存器逻辑 - std::vector send_buffer; - send_buffer.push_back(0xEB); - send_buffer.push_back(0x90); - send_buffer.push_back(static_cast(std::stoi(id_value))); // 将 ID 转换为 unsigned char - size_t num_values = values_to_write.size(); - auto data_length = static_cast(num_values * 2 + 3); - send_buffer.push_back(data_length); - send_buffer.push_back(0x12); // 写寄存器命令 - send_buffer.push_back(static_cast(address_decimal & 0xFF)); // 地址低八位 - send_buffer.push_back(static_cast((address_decimal >> 8) & 0xFF)); // 地址高八位 - - // 将要写入的值添加到数据包中 - for (int value : values_to_write) { - send_buffer.push_back(static_cast(value & 0xFF)); // 写入值低八位 - send_buffer.push_back(static_cast((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 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 first_chunk(values_to_write.begin(), values_to_write.begin() + std::min(4, (int)values_to_write.size())); - std::vector second_chunk(values_to_write.begin() + first_chunk.size(), values_to_write.end()); - - // 构造并发送第一段数据 - auto construct_and_send = [&](const std::vector& chunk, int addr) { - // 转换地址为二进制->十六进制 - std::string result_bin = convertAddressToBinary_write(addr, id_value); - std::string result_hex = binaryToHex(result_bin); - std::vector processed_data = processHexData(result_hex); - - // 构造数据帧 - std::vector 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 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 read_register(serial_interface& serial, int address_decimal, const std::string& id_value, - size_t register_length, size_t length_to_read) { - - std::vector send_buffer; - if (serial.getCommunicationMode() == CommunicationMode::RS485) { - // RS485模式下的读寄存器逻辑 - send_buffer.push_back(0xEB); - send_buffer.push_back(0x90); - send_buffer.push_back(static_cast(std::stoi(id_value))); // 将 ID 转换为 unsigned char - send_buffer.push_back(0x04); - send_buffer.push_back(0x11); - send_buffer.push_back(static_cast(address_decimal & 0xFF)); // 地址低八位 - send_buffer.push_back(static_cast((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 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 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 parsed_values; - size_t bytes_read = 0; - - while (bytes_read < register_length) { - std::vector send_buffer; - - // 生成地址相关数据 - std::string result_bin = convertAddressToBinary_read(address_decimal, id_value); - std::string result_hex = binaryToHex(result_bin); - std::vector 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(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 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(data_length); // 地址后移8字节 - } - - return parsed_values; - } - - - std::vector 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 all_parsed_values; - - size_t bytes_read = 0; - while (bytes_read < register_length) { - std::vector send_buffer; - std::vector parsed_values; - std::string result_bin = convertAddressToBinary_read(address_decimal, id_value); - std::string result_hex = binaryToHex(result_bin); - std::vector 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 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 parse_register(const std::vector& data,int start_byte, size_t register_length,int per_byte){ - - std::vector 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 parse_error(unsigned char errorCode) { - - std::vector 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; - } -} \ No newline at end of file diff --git a/src/hardware_manager/CMakeLists.txt b/src/hardware_manager/CMakeLists.txt index e8cf37da..7c402efb 100644 --- a/src/hardware_manager/CMakeLists.txt +++ b/src/hardware_manager/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/src/hardware_manager/hardware_factory.cpp b/src/hardware_manager/hardware_factory.cpp index 8de2ce16..f4ea0c40 100644 --- a/src/hardware_manager/hardware_factory.cpp +++ b/src/hardware_manager/hardware_factory.cpp @@ -6,7 +6,7 @@ #include using namespace std; -using namespace cmvr::device; +using namespace cmvr::hardware; template std::shared_ptr HardwareFactory::create(const XmlNode&); diff --git a/src/hardware_manager/hardware_manager.cpp b/src/hardware_manager/hardware_manager.cpp index 4ae47dbd..27a95c4a 100644 --- a/src/hardware_manager/hardware_manager.cpp +++ b/src/hardware_manager/hardware_manager.cpp @@ -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::instance_ = nullptr; HardWareManager::HardWareManager(const XmlNode& cfg) {