diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d645254 --- /dev/null +++ b/.clang-format @@ -0,0 +1,94 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +ColumnLimit: 100 +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortBlocksOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakAssignment: 2 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: C++17 diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..b02d4a2 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,59 @@ +--- +Checks: > + -*, + bugprone-*, + cert-*, + cppcoreguidelines-*, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -cppcoreguidelines-pro-type-union-access, + -cppcoreguidelines-pro-bounds-constant-array-index, + -cppcoreguidelines-avoid-non-const-global-variables, + misc-*, + -misc-non-private-member-variables-in-classes, + performance-*, + -performance-avoid-endl, + readability-*, + -readability-magic-numbers, + -readability-identifier-length, + -readability-function-cognitive-complexity, + modernize-*, + -modernize-use-trailing-return-type, + -modernize-avoid-c-arrays + +WarningsAsErrors: '' +HeaderFilterRegex: '.*' +AnalyzeTemporaryDtors: false +FormatStyle: 'file' +User: '' +CheckOptions: + - key: readability-identifier-naming.NamespaceCase + value: lower_case + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.StructCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: camelBack + - key: readability-identifier-naming.VariableCase + value: camelBack + - key: readability-identifier-naming.ParameterCase + value: camelBack + - key: readability-identifier-naming.MemberCase + value: camelBack + - key: readability-identifier-naming.PrivateMemberPrefix + value: m_ + - key: readability-identifier-naming.ProtectedMemberPrefix + value: m_ + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.EnumConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.ConstantCase + value: UPPER_CASE + - key: readability-identifier-naming.MacroDefinitionCase + value: UPPER_CASE + - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor + value: true + - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions + value: true diff --git a/CMakeLists.txt b/CMakeLists.txt index df51191..ef21a2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ -cmake_minimum_required(VERSION 3.5) -project(MyProject) +cmake_minimum_required(VERSION 3.15) +project(LinkerHand-CPP-SDK + VERSION 1.1.7 + LANGUAGES CXX + DESCRIPTION "LinkerHand C++ SDK for robotic hand control" +) if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") set(LIB_SUBDIR "x86_64") @@ -60,6 +64,53 @@ target_link_libraries(toolset_example ${LINKER_HAND_LIB} pthread) add_executable(action_group_show_l10 examples/action_group_show_l10.cpp) target_link_libraries(action_group_show_l10 ${LINKER_HAND_LIB} pthread) +#----------------------------------------------------------------------------- +# INSTALL TARGETS +#----------------------------------------------------------------------------- +# 安装头文件 +install(DIRECTORY include/ + DESTINATION include/linkerhand-cpp-sdk + FILES_MATCHING PATTERN "*.h" +) + +# 安装库文件 +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/lib/${LIB_SUBDIR}) + install(DIRECTORY lib/${LIB_SUBDIR}/ + DESTINATION lib/linkerhand-cpp-sdk/${LIB_SUBDIR} + FILES_MATCHING PATTERN "*.so*" + ) +endif() + +#----------------------------------------------------------------------------- +# PACKAGE CONFIGURATION +#----------------------------------------------------------------------------- +include(CMakePackageConfigHelpers) + +# 创建包配置文件 +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/LinkerHandCPPSDKConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) + +# 设置包配置变量(用于 configure_file) +set(PACKAGE_INCLUDE_INSTALL_DIR "include/linkerhand-cpp-sdk") +set(PACKAGE_LIB_INSTALL_DIR "lib/linkerhand-cpp-sdk/${LIB_SUBDIR}") + +# 创建包配置文件模板 +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/LinkerHandCPPSDKConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/LinkerHandCPPSDKConfig.cmake" + @ONLY +) + +# 安装包配置文件 +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/LinkerHandCPPSDKConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/LinkerHandCPPSDKConfigVersion.cmake" + DESTINATION lib/cmake/LinkerHandCPPSDK +) + #----------------------------------------------------------------------------- # TESTING #----------------------------------------------------------------------------- diff --git a/cmake/LinkerHandCPPSDKConfig.cmake.in b/cmake/LinkerHandCPPSDKConfig.cmake.in new file mode 100644 index 0000000..684b172 --- /dev/null +++ b/cmake/LinkerHandCPPSDKConfig.cmake.in @@ -0,0 +1,45 @@ +@PACKAGE_INIT@ + +# 确定系统架构 +if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") + set(LIB_SUBDIR "x86_64") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64") + set(LIB_SUBDIR "aarch64") +else() + set(LIB_SUBDIR "x86_64") +endif() + +# 设置包含目录和库目录(相对于安装前缀) +set(LinkerHandCPPSDK_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/../../@PACKAGE_INCLUDE_INSTALL_DIR@") +set(LinkerHandCPPSDK_LIB_DIR "${CMAKE_CURRENT_LIST_DIR}/../../@PACKAGE_LIB_INSTALL_DIR@") + +# 也支持从构建目录查找(用于开发时) +list(APPEND LinkerHandCPPSDK_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/../../include/linkerhand-cpp-sdk") +list(APPEND LinkerHandCPPSDK_LIB_DIR "${CMAKE_CURRENT_LIST_DIR}/../../lib/linkerhand-cpp-sdk/${LIB_SUBDIR}") + +# 查找库文件 +find_library(LinkerHandCPPSDK_LIBRARY + NAMES linkerhand_cpp_sdk + PATHS ${LinkerHandCPPSDK_LIB_DIR} + NO_DEFAULT_PATH +) + +# 检查库文件是否存在 +if(NOT LinkerHandCPPSDK_LIBRARY) + message(FATAL_ERROR "LinkerHandCPPSDK library not found in ${LinkerHandCPPSDK_LIB_DIR}") +endif() + +# 设置变量供外部使用 +set(LinkerHandCPPSDK_FOUND TRUE) +set(LinkerHandCPPSDK_VERSION @PROJECT_VERSION@) + +# 创建导入目标 +if(NOT TARGET LinkerHandCPPSDK::LinkerHandCPPSDK) + add_library(LinkerHandCPPSDK::LinkerHandCPPSDK SHARED IMPORTED) + set_target_properties(LinkerHandCPPSDK::LinkerHandCPPSDK PROPERTIES + IMPORTED_LOCATION "${LinkerHandCPPSDK_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LinkerHandCPPSDK_INCLUDE_DIR}" + ) +endif() + +check_required_components(LinkerHandCPPSDK) diff --git a/examples/toolset_example.cpp b/examples/toolset_example.cpp index 634ff95..d6436b9 100644 --- a/examples/toolset_example.cpp +++ b/examples/toolset_example.cpp @@ -72,8 +72,8 @@ void exit() running = false; std::string can_channel; - if (channel == COMM_TYPE::COMM_CAN_0) can_channel = "can0"; - if (channel == COMM_TYPE::COMM_CAN_1) can_channel = "can1"; + if (channel == COMM_CAN_0) can_channel = "can0"; + if (channel == COMM_CAN_1) can_channel = "can1"; // system(std::string("sudo /usr/sbin/ip link set " + can_channel + " down").c_str()); exit(0); @@ -525,13 +525,13 @@ int main() switch (choice) { case 1: - channel = COMM_TYPE::COMM_CAN_0; + channel = COMM_CAN_0; break; case 2: - channel = COMM_TYPE::COMM_CAN_1; + channel = COMM_CAN_1; break; case 3: - channel = COMM_TYPE::COMM_ETHERCAT; + channel = COMM_ETHERCAT; break; case 0: exit(); diff --git a/include/CanBus.h b/include/CanBus.h index 2be4829..e8291f6 100644 --- a/include/CanBus.h +++ b/include/CanBus.h @@ -1,6 +1,6 @@ #ifdef __linux__ -#ifndef CAN_BUS_H -#define CAN_BUS_H +#ifndef LINKERHAND_CAN_BUS_H +#define LINKERHAND_CAN_BUS_H #include #include @@ -25,9 +25,13 @@ #include "ICanBus.h" -namespace Communication //Communicator -{ - class CanBus : public ICanBus +namespace linkerhand { +namespace communication { + +/** + * @brief Linux CAN 总线实现 + */ +class CanBus : public linkerhand::communication::ICanBus { public: CanBus(const std::string& interface, int bitrate, const LINKER_HAND linkerhand); @@ -62,7 +66,12 @@ namespace Communication //Communicator LINKER_HAND linker_hand; }; -} +} // namespace communication +} // namespace linkerhand + +// 向后兼容:在全局命名空间中提供别名 +namespace Communication = linkerhand::communication; + #endif -#endif // CAN_BUS_H +#endif // LINKERHAND_CAN_BUS_H diff --git a/include/CanBusFactory.h b/include/CanBusFactory.h index 3a8e795..e24f3cd 100644 --- a/include/CanBusFactory.h +++ b/include/CanBusFactory.h @@ -1,5 +1,5 @@ -#ifndef CAN_BUS_FACTORY_H -#define CAN_BUS_FACTORY_H +#ifndef LINKERHAND_CAN_BUS_FACTORY_H +#define LINKERHAND_CAN_BUS_FACTORY_H #include "ICanBus.h" #include "CanBus.h" @@ -10,8 +10,8 @@ #include -namespace Communication -{ +namespace linkerhand { +namespace communication { class CanBusFactory { public: @@ -31,17 +31,17 @@ namespace Communication if (interfaceOrChannel == "can1") { channel = PCAN_USBBUS2; } - return std::make_unique(channel, baudrate, linkerHand); + return std::make_unique(channel, baudrate, linkerHand); #else // Linux/Unix 平台 if (interfaceOrChannel == "can0" || interfaceOrChannel == "can1") { - return std::make_unique(interfaceOrChannel, bitrate, linkerHand); + return std::make_unique(interfaceOrChannel, bitrate, linkerHand); } #if USE_ETHERCAT else if (interfaceOrChannel == "ethercat") { - return std::make_unique(handId); + return std::make_unique(handId); } #endif @@ -53,6 +53,10 @@ namespace Communication #endif } }; -} +} // namespace communication +} // namespace linkerhand -#endif // CAN_BUS_FACTORY_H +// 向后兼容:在全局命名空间中提供别名 +namespace Communication = linkerhand::communication; + +#endif // LINKERHAND_CAN_BUS_FACTORY_H diff --git a/include/CanFrame.h b/include/CanFrame.h index d2689eb..c0c3b6d 100644 --- a/include/CanFrame.h +++ b/include/CanFrame.h @@ -1,5 +1,5 @@ -#ifndef CAN_FRAME_H -#define CAN_FRAME_H +#ifndef LINKERHAND_CAN_FRAME_H +#define LINKERHAND_CAN_FRAME_H #include #include @@ -27,4 +27,4 @@ struct CANFrame }; -#endif // CAN_FRAME_H \ No newline at end of file +#endif // LINKERHAND_CAN_FRAME_H \ No newline at end of file diff --git a/include/Common.h b/include/Common.h index 9b8626d..fa6b9dc 100644 --- a/include/Common.h +++ b/include/Common.h @@ -1,6 +1,7 @@ -#ifndef COMMON_H -#define COMMON_H +#ifndef LINKERHAND_COMMON_H +#define LINKERHAND_COMMON_H +// 为了与预编译库兼容,保持旧的枚举定义(非枚举类) enum LINKER_HAND { O6, L6, @@ -23,11 +24,45 @@ enum COMM_TYPE { COMM_ETHERCAT }; -namespace Common -{ +namespace linkerhand { + +/** + * @brief 通用配置和版本信息 + */ +namespace Common { inline float current_hand_version = 1.0; } + +/** + * @brief 新的枚举类(用于未来版本,当前保持向后兼容) + * + * 注意:当前库使用旧的枚举类型,这些枚举类用于未来版本 + */ +enum class HandModel { + O6, + L6, + L7, + L10, + L20, + L21, + L25 +}; + +enum class HandType { + LEFT = 0x28, + RIGHT = 0x27 +}; + +enum class CommType { + CAN_0, + CAN_1, + MODBUS, + ETHERCAT +}; + +} // namespace linkerhand + #define SEND_DEBUG 0 #define RECV_DEBUG 0 -#endif // COMMON_H +#endif // LINKERHAND_COMMON_H diff --git a/include/ErrorCode.h b/include/ErrorCode.h new file mode 100644 index 0000000..cc4f1e7 --- /dev/null +++ b/include/ErrorCode.h @@ -0,0 +1,146 @@ +#ifndef LINKERHAND_ERROR_CODE_H +#define LINKERHAND_ERROR_CODE_H + +#include +#include + +namespace linkerhand { + +/** + * @brief 错误码枚举 + * + * 定义 LinkerHand SDK 的所有错误类型 + */ +enum class HandError { + Success = 0, ///< 成功 + UnsupportedFeature, ///< 不支持的功能 + CommunicationError, ///< 通信错误 + InvalidParameter, ///< 无效参数 + DeviceNotFound, ///< 设备未找到 + Timeout, ///< 超时 + InvalidState, ///< 无效状态 + OperationFailed, ///< 操作失败 + NotInitialized, ///< 未初始化 + AlreadyInitialized, ///< 已初始化 + OutOfRange, ///< 超出范围 + UnknownError ///< 未知错误 +}; + +/** + * @brief 错误类别 + * + * 实现 std::error_category 接口,用于错误码分类 + */ +class HandErrorCategory : public std::error_category { +public: + const char* name() const noexcept override { + return "LinkerHand"; + } + + std::string message(int ev) const override { + switch (static_cast(ev)) { + case HandError::Success: + return "Success"; + case HandError::UnsupportedFeature: + return "Unsupported feature"; + case HandError::CommunicationError: + return "Communication error"; + case HandError::InvalidParameter: + return "Invalid parameter"; + case HandError::DeviceNotFound: + return "Device not found"; + case HandError::Timeout: + return "Timeout"; + case HandError::InvalidState: + return "Invalid state"; + case HandError::OperationFailed: + return "Operation failed"; + case HandError::NotInitialized: + return "Not initialized"; + case HandError::AlreadyInitialized: + return "Already initialized"; + case HandError::OutOfRange: + return "Out of range"; + case HandError::UnknownError: + default: + return "Unknown error"; + } + } +}; + +/** + * @brief 获取错误类别实例 + */ +inline const HandErrorCategory& hand_error_category() { + static HandErrorCategory instance; + return instance; +} + +/** + * @brief 将 HandError 转换为 std::error_code + */ +inline std::error_code make_error_code(HandError e) { + return std::error_code(static_cast(e), hand_error_category()); +} + +/** + * @brief 异常类:LinkerHand 异常基类 + */ +class HandException : public std::runtime_error { +public: + HandException(HandError error, const std::string& message) + : std::runtime_error(message), error_code_(error) {} + + HandError error_code() const noexcept { + return error_code_; + } + +private: + HandError error_code_; +}; + +/** + * @brief 异常类:不支持的功能 + */ +class UnsupportedFeatureException : public HandException { +public: + explicit UnsupportedFeatureException(const std::string& feature_name) + : HandException(HandError::UnsupportedFeature, + "Unsupported feature: " + feature_name), + feature_name_(feature_name) {} + + const std::string& feature_name() const noexcept { + return feature_name_; + } + +private: + std::string feature_name_; +}; + +/** + * @brief 异常类:通信错误 + */ +class CommunicationException : public HandException { +public: + explicit CommunicationException(const std::string& message) + : HandException(HandError::CommunicationError, message) {} +}; + +/** + * @brief 异常类:无效参数 + */ +class InvalidParameterException : public HandException { +public: + explicit InvalidParameterException(const std::string& message) + : HandException(HandError::InvalidParameter, message) {} +}; + +} // namespace linkerhand + +// 注册错误码到标准库 +namespace std { + template<> + struct is_error_code_enum : true_type {}; +} + +#endif // LINKERHAND_ERROR_CODE_H diff --git a/include/EtherCAT.h b/include/EtherCAT.h index c98dcdd..fae6daa 100644 --- a/include/EtherCAT.h +++ b/include/EtherCAT.h @@ -1,6 +1,6 @@ #ifdef __linux__ -#ifndef ETHERCAT_H -#define ETHERCAT_H +#ifndef LINKERHAND_ETHERCAT_H +#define LINKERHAND_ETHERCAT_H #include #include @@ -24,10 +24,13 @@ constexpr uint32_t PERIOD_US = 1000; // 10ms constexpr unsigned int MASTER_INDEX = 0; constexpr uint32_t cycle_ns = 8000000; // 8ms 周期 -namespace Communication //Communicator -{ +namespace linkerhand { +namespace communication { - class EtherCAT : public ICanBus { +/** + * @brief EtherCAT 通信实现 + */ +class EtherCAT : public ICanBus { public: EtherCAT(const uint32_t handId); @@ -113,7 +116,11 @@ namespace Communication //Communicator bool is_detection_hand; uint32_t handId_; }; -} +} // namespace communication +} // namespace linkerhand -#endif // ETHERCAT_H +// 向后兼容:在全局命名空间中提供别名 +namespace Communication = linkerhand::communication; + +#endif // LINKERHAND_ETHERCAT_H #endif diff --git a/include/HandFactory.h b/include/HandFactory.h index 7d14e86..cde1e7d 100644 --- a/include/HandFactory.h +++ b/include/HandFactory.h @@ -1,5 +1,5 @@ -#ifndef HAND_FACTORY_H -#define HAND_FACTORY_H +#ifndef LINKERHAND_HAND_FACTORY_H +#define LINKERHAND_HAND_FACTORY_H #include "IHand.h" #include "LinkerHandL6.h" @@ -7,14 +7,31 @@ #include "LinkerHandL10.h" #include "LinkerHandL20.h" #include "LinkerHandL25.h" - #include "ModbusLinkerHandL10.h" +#include "Common.h" + +namespace linkerhand { +namespace factory { +/** + * @brief 手型号工厂类 + * + * 根据手型号、手类型和通信类型创建对应的手实例 + */ class HandFactory { public: - static std::unique_ptr createHand(LINKER_HAND type, uint32_t handId, COMM_TYPE commType) { + /** + * @brief 创建手实例 + * @param type 手型号 + * @param handId 手ID(左手/右手) + * @param commType 通信类型 + * @return 手实例的智能指针 + * @throws std::invalid_argument 如果参数无效 + */ + static std::unique_ptr createHand(LINKER_HAND type, uint32_t handId, COMM_TYPE commType) { - if (handId != HAND_TYPE::LEFT && handId != HAND_TYPE::RIGHT) + if (handId != static_cast(LEFT) && + handId != static_cast(RIGHT)) { throw std::invalid_argument("Unsupported hand type"); } @@ -24,16 +41,16 @@ class HandFactory { switch (commType) { - case COMM_TYPE::COMM_CAN_0: + case COMM_CAN_0: canChannel = "can0"; break; - case COMM_TYPE::COMM_CAN_1: + case COMM_CAN_1: canChannel = "can1"; break; - case COMM_TYPE::COMM_MODBUS: + case COMM_MODBUS: canChannel = "modbus"; break; - case COMM_TYPE::COMM_ETHERCAT: + case COMM_ETHERCAT: canChannel = "ethercat"; break; default: @@ -43,26 +60,26 @@ class HandFactory { if (canChannel == "can0" || canChannel == "can1" || canChannel == "ethercat") { switch (type) { - case LINKER_HAND::O6: - return std::make_unique(handId, canChannel, baudrate); + case O6: + return std::unique_ptr(std::make_unique(handId, canChannel, baudrate)); break; - case LINKER_HAND::L6: - return std::make_unique(handId, canChannel, baudrate); + case L6: + return std::unique_ptr(std::make_unique(handId, canChannel, baudrate)); break; - case LINKER_HAND::L7: - return std::make_unique(handId, canChannel, baudrate); + case L7: + return std::unique_ptr(std::make_unique(handId, canChannel, baudrate)); break; - case LINKER_HAND::L10: - return std::make_unique(handId, canChannel, baudrate); + case L10: + return std::unique_ptr(std::make_unique(handId, canChannel, baudrate)); break; - case LINKER_HAND::L20: - return std::make_unique(handId, canChannel, baudrate); + case L20: + return std::unique_ptr(std::make_unique(handId, canChannel, baudrate)); break; - case LINKER_HAND::L21: - return std::make_unique(handId, canChannel, baudrate, 1); + case L21: + return std::unique_ptr(std::make_unique(handId, canChannel, baudrate, 1)); break; - case LINKER_HAND::L25: - return std::make_unique(handId, canChannel, baudrate, 0); + case L25: + return std::unique_ptr(std::make_unique(handId, canChannel, baudrate, 0)); break; default: throw std::invalid_argument("Unknown hand type"); @@ -70,8 +87,8 @@ class HandFactory { } else if (canChannel == "modbus") { #if USE_RMAN switch (type) { - case LINKER_HAND::L10: - return std::make_unique(handId); + case L10: + return std::unique_ptr(std::make_unique(handId)); default: throw std::invalid_argument("Unknown hand type"); break; @@ -85,4 +102,10 @@ class HandFactory { } }; -#endif // HAND_FACTORY_H +} // namespace factory +} // namespace linkerhand + +// 向后兼容:在全局命名空间中提供别名 +using HandFactory = linkerhand::factory::HandFactory; + +#endif // LINKERHAND_HAND_FACTORY_H diff --git a/include/ICanBus.h b/include/ICanBus.h index 5922b84..305ad03 100644 --- a/include/ICanBus.h +++ b/include/ICanBus.h @@ -1,22 +1,45 @@ -#ifndef I_CAN_BUS_H -#define I_CAN_BUS_H +#ifndef LINKERHAND_ICANBUS_H +#define LINKERHAND_ICANBUS_H #include #include #include #include "Common.h" -#include "CanFrame.h" // 包含公共 CAN 帧声明 +#include "CanFrame.h" -namespace Communication -{ - class ICanBus - { - public: - virtual ~ICanBus() = default; +namespace linkerhand { +namespace communication { - virtual void send(const std::vector& data, uint32_t can_id, const bool wait = false) = 0; - virtual CANFrame recv(uint32_t& id) = 0; - }; -} +/** + * @brief CAN 总线接口 + * + * 定义 CAN 总线通信的标准接口 + */ +class ICanBus { +public: + virtual ~ICanBus() = default; -#endif // I_CAN_BUS_H + /** + * @brief 发送 CAN 帧 + * @param data 要发送的数据 + * @param can_id CAN 帧 ID + * @param wait 是否等待发送完成(默认 false) + */ + virtual void send(const std::vector& data, uint32_t can_id, + const bool wait = false) = 0; + + /** + * @brief 接收 CAN 帧 + * @param id CAN 帧 ID(输出参数) + * @return 接收到的 CAN 帧 + */ + virtual CANFrame recv(uint32_t& id) = 0; +}; + +} // namespace communication +} // namespace linkerhand + +// 向后兼容的别名 +namespace Communication = linkerhand::communication; + +#endif // LINKERHAND_ICANBUS_H diff --git a/include/ICommunication.h b/include/ICommunication.h index 16d6f04..df6d6ab 100644 --- a/include/ICommunication.h +++ b/include/ICommunication.h @@ -1,15 +1,44 @@ -#include +#ifndef LINKERHAND_ICOMMUNICATION_H +#define LINKERHAND_ICOMMUNICATION_H + #include -#include -#include - -// namespace LinkerHandComm -// { - class ICommunication - { - public: - virtual ~ICommunication() = default; - virtual void send(const std::vector& data, uint32_t &id, const int &start_address = 0, const int &num = 0) = 0; - virtual std::vector recv(uint32_t& id, const int &start_address = 0, const int &num = 0) = 0; - }; -// } \ No newline at end of file +#include + +namespace linkerhand { +namespace communication { + +/** + * @brief 通信接口基类 + * + * 定义通用的通信接口,支持 ModBus 等协议 + */ +class ICommunication { +public: + virtual ~ICommunication() = default; + + /** + * @brief 发送数据 + * @param data 要发送的数据 + * @param id 设备ID(输入输出参数) + * @param start_address 起始地址(默认0) + * @param num 数量(默认0) + */ + virtual void send(const std::vector& data, uint32_t &id, + const int &start_address = 0, const int &num = 0) = 0; + + /** + * @brief 接收数据 + * @param id 设备ID(输入输出参数) + * @param start_address 起始地址(默认0) + * @param num 数量(默认0) + * @return 接收到的数据 + */ + virtual std::vector recv(uint32_t& id, + const int &start_address = 0, + const int &num = 0) = 0; +}; + +} // namespace communication +} // namespace linkerhand + +#endif // LINKERHAND_ICOMMUNICATION_H \ No newline at end of file diff --git a/include/IHand.h b/include/IHand.h index eebdca5..27e4faa 100644 --- a/include/IHand.h +++ b/include/IHand.h @@ -1,5 +1,5 @@ -#ifndef I_HAND_H -#define I_HAND_H +#ifndef LINKERHAND_IHAND_H +#define LINKERHAND_IHAND_H #include #include @@ -8,10 +8,21 @@ #include #include #include +#include #include "RangeToArc.h" #include "Common.h" +#include "ErrorCode.h" +namespace linkerhand { +namespace hand { + +/** + * @brief 灵巧手接口基类 + * + * 定义所有手型号必须实现的基础接口 + * 注意:不支持的方法会抛出异常而不是返回空值 + */ class IHand { public: @@ -21,172 +32,151 @@ class IHand virtual void setJointPositionArc(const std::vector &jointAngles) { (void) jointAngles; - printUnsupportedFeature("setJointPositionArc"); + throw UnsupportedFeatureException("setJointPositionArc"); } // 获取速度数据 virtual std::vector getSpeed() { - printUnsupportedFeature("getSpeed"); - return {}; + throw UnsupportedFeatureException("getSpeed"); } // 设置关节速度 virtual void setSpeed(const std::vector &speed) { (void) speed; - printUnsupportedFeature("setSpeed"); + throw UnsupportedFeatureException("setSpeed"); } // 获取当前关节位置 virtual std::vector getCurrentStatus() { - printUnsupportedFeature("getCurrentStatus"); - return {}; + throw UnsupportedFeatureException("getCurrentStatus"); } virtual std::vector getCurrentStatusArc() { - printUnsupportedFeature("getCurrentPositionArc"); - return {}; + throw UnsupportedFeatureException("getCurrentStatusArc"); } // 获取电机故障码 virtual std::vector getFaultCode() { - printUnsupportedFeature("getFaultCode"); - return {}; + throw UnsupportedFeatureException("getFaultCode"); } // 获取电机电流 virtual std::vector getCurrent() { - printUnsupportedFeature("getCurrent"); - return {}; + throw UnsupportedFeatureException("getCurrent"); } // ------------------------------------------------------ // 获取压感数据 virtual std::vector> getForce(const int type) { (void)type; - printUnsupportedFeature("getForce"); - return {}; + throw UnsupportedFeatureException("getForce"); } virtual std::vector>> getForce() { - printUnsupportedFeature("getForceTest"); - return {}; + throw UnsupportedFeatureException("getForce"); } // 获取大拇指压感数据 virtual std::vector getThumbForce() { - printUnsupportedFeature("getThumbForce"); - return {}; + throw UnsupportedFeatureException("getThumbForce"); } // 获取食指压感数据 virtual std::vector getIndexForce() { - printUnsupportedFeature("getIndexForce"); - return {}; + throw UnsupportedFeatureException("getIndexForce"); } // 获取中指压感数据 virtual std::vector getMiddleForce() { - printUnsupportedFeature("getMiddleForce"); - return {}; + throw UnsupportedFeatureException("getMiddleForce"); } // 获取无名指压感数据 virtual std::vector getRingForce() { - printUnsupportedFeature("getRingForce"); - return {}; + throw UnsupportedFeatureException("getRingForce"); } // 获取小拇指压感数据 virtual std::vector getLittleForce() { - printUnsupportedFeature("getLittleForce"); - return {}; + throw UnsupportedFeatureException("getLittleForce"); } // ------------------------------------------------------ // 获取五指法向力 virtual std::vector getNormalForce() { - printUnsupportedFeature("getNormalForce"); - return {}; + throw UnsupportedFeatureException("getNormalForce"); } // 获取五指切向力 virtual std::vector getTangentialForce() { - printUnsupportedFeature("getTangentialForce"); - return {}; + throw UnsupportedFeatureException("getTangentialForce"); } // 获取五指法向力方向 virtual std::vector getTangentialForceDir() { - printUnsupportedFeature("getTangentialForceDir"); - return {}; + throw UnsupportedFeatureException("getTangentialForceDir"); } // 获取五指接近感应 virtual std::vector getApproachInc() { - printUnsupportedFeature("getApproachInc"); - return {}; + throw UnsupportedFeatureException("getApproachInc"); } // ------------------------------------------------------ // 设置扭矩 L20暂不支持 virtual void setTorque(const std::vector &torque) { (void)torque; - printUnsupportedFeature("setTorque"); + throw UnsupportedFeatureException("setTorque"); } // 获取电机扭矩 L20暂不支持 virtual std::vector getTorque() { - printUnsupportedFeature("getTorque"); - return {}; + throw UnsupportedFeatureException("getTorque"); } // 获取电机温度 L20暂不支持 virtual std::vector getTemperature() { - printUnsupportedFeature("getTemperature"); - return {}; + throw UnsupportedFeatureException("getTemperature"); } // 获取版本号 目前仅支持L10 virtual std::string getVersion() { - printUnsupportedFeature("getVersion"); - return ""; + throw UnsupportedFeatureException("getVersion"); } // 获取设备ID L20协议 virtual std::vector getUID() { - printUnsupportedFeature("getUID"); - return {}; + throw UnsupportedFeatureException("getUID"); } // 手指堵转或过流判断计数阀值 L20协议 virtual std::vector getRotorLockCount() { - printUnsupportedFeature("getRotorLockCount"); - return {}; + throw UnsupportedFeatureException("getRotorLockCount"); } // 清除电机故障码 目前仅支持L20 virtual void clearFaultCode(const std::vector &code) { (void)code; - printUnsupportedFeature("clearFaultCode"); + throw UnsupportedFeatureException("clearFaultCode"); } // 设置电流 目前仅支持L20 virtual void setCurrent(const std::vector ¤t) { (void)current; - printUnsupportedFeature("setCurrent"); + throw UnsupportedFeatureException("setCurrent"); } // 设置电机使能 目前仅支持L25 virtual void setMotorEnable(const std::vector &enable) { (void)enable; - printUnsupportedFeature("setMotorEnable"); + throw UnsupportedFeatureException("setMotorEnable"); } // 设置电机使能 目前仅支持L25 virtual void setMotorDisable(const std::vector &disable) { (void)disable; - printUnsupportedFeature("setMotorDisable"); + throw UnsupportedFeatureException("setMotorDisable"); } // --------------------------------------------------------------------- @@ -231,16 +221,10 @@ class IHand return ss.str(); } -protected: - void printUnsupportedFeature(const std::string &featureName) const - { - static std::set printedFeatures; - if (printedFeatures.find(featureName) == printedFeatures.end()) - { - std::cout << featureName << " Not currently supported!" << std::endl; - printedFeatures.insert(featureName); - } - } }; -#endif // I_HAND_H + +} // namespace hand +} // namespace linkerhand + +#endif // LINKERHAND_IHAND_H diff --git a/include/LinkerHandApi.h b/include/LinkerHandApi.h index 0d7cbdf..3acdeef 100644 --- a/include/LinkerHandApi.h +++ b/include/LinkerHandApi.h @@ -1,15 +1,32 @@ -#ifndef LINKER_HAND_API_H -#define LINKER_HAND_API_H +#ifndef LINKERHAND_API_H +#define LINKERHAND_API_H #include #include #include +#include #include "HandFactory.h" +#include "Common.h" +#include "IHand.h" +/** + * @brief LinkerHand API 主类 + * + * 提供统一的接口用于控制各种型号的灵巧手设备 + * + * 注意:为了与预编译库兼容,此类保持在全局命名空间 + */ class LinkerHandApi { public: - LinkerHandApi(const LINKER_HAND &handJoint, const HAND_TYPE &handType, const COMM_TYPE commType = COMM_CAN_0); + /** + * @brief 构造函数 + * @param handJoint 手型号(LINKER_HAND 枚举) + * @param handType 手类型(左手/右手) + * @param commType 通信类型(默认 CAN_0) + */ + LinkerHandApi(const LINKER_HAND &handJoint, const HAND_TYPE &handType, + const COMM_TYPE commType = COMM_CAN_0); ~LinkerHandApi(); // 设置关节位置 @@ -60,11 +77,18 @@ class LinkerHandApi void getApproachInc(); private: - std::unique_ptr hand; + std::unique_ptr hand; uint32_t handId; public: LINKER_HAND handJoint_; HAND_TYPE handType_; }; -#endif +// 在新命名空间中提供类型别名(用于未来版本) +namespace linkerhand { +namespace api { + using LinkerHandApi = ::LinkerHandApi; +} // namespace api +} // namespace linkerhand + +#endif // LINKERHAND_API_H diff --git a/include/LinkerHandL10.h b/include/LinkerHandL10.h index 50d4c50..ca26216 100644 --- a/include/LinkerHandL10.h +++ b/include/LinkerHandL10.h @@ -1,5 +1,5 @@ -#ifndef LINKER_HAND_L10_H -#define LINKER_HAND_L10_H +#ifndef LINKERHAND_L10_H +#define LINKERHAND_L10_H #include #include @@ -52,7 +52,7 @@ typedef enum PALM_TOUCH = 0xB6, // 手掌指触觉传感 }FRAME_PROPERTY; -class LinkerHand : public IHand +class LinkerHand : public linkerhand::hand::IHand { public: LinkerHand(uint32_t handId, const std::string &canChannel, int baudrate); @@ -145,4 +145,4 @@ class LinkerHand : public IHand uint8_t sensor_type = 0; }; } // namespace LinkerHandL10 -#endif // LINKER_HAND_L10_H \ No newline at end of file +#endif // LINKERHAND_L10_H \ No newline at end of file diff --git a/include/LinkerHandL20.h b/include/LinkerHandL20.h index c3f18a2..53cd1d9 100644 --- a/include/LinkerHandL20.h +++ b/include/LinkerHandL20.h @@ -1,5 +1,5 @@ -#ifndef LINKER_HAND_L20_H -#define LINKER_HAND_L20_H +#ifndef LINKERHAND_L20_H +#define LINKERHAND_L20_H #include #include @@ -62,7 +62,7 @@ typedef enum }FRAME_PROPERTY; -class LinkerHand : public IHand { +class LinkerHand : public linkerhand::hand::IHand { public: LinkerHand(uint32_t handId, const std::string& canChannel, int baudrate); ~LinkerHand(); @@ -169,4 +169,4 @@ class LinkerHand : public IHand { uint8_t sensor_type = 0; }; } -#endif // LINKER_HAND_L20_H \ No newline at end of file +#endif // LINKERHAND_L20_H \ No newline at end of file diff --git a/include/LinkerHandL25.h b/include/LinkerHandL25.h index d6e7a5c..01a3684 100644 --- a/include/LinkerHandL25.h +++ b/include/LinkerHandL25.h @@ -1,5 +1,5 @@ -#ifndef LINKER_HAND_L25_H -#define LINKER_HAND_L25_H +#ifndef LINKERHAND_L25_H +#define LINKERHAND_L25_H #include #include @@ -128,7 +128,7 @@ typedef enum }FRAME_PROPERTY; -class LinkerHand : public IHand { +class LinkerHand : public linkerhand::hand::IHand { public: LinkerHand(uint32_t handId, const std::string& canChannel, int baudrate, const int currentHandType = 0); ~LinkerHand(); @@ -426,4 +426,4 @@ class LinkerHand : public IHand { std::vector>> touch_mats; }; } -#endif // LINKER_HAND_L25_H \ No newline at end of file +#endif // LINKERHAND_L25_H \ No newline at end of file diff --git a/include/LinkerHandL6.h b/include/LinkerHandL6.h index 8810bc4..e96c20f 100644 --- a/include/LinkerHandL6.h +++ b/include/LinkerHandL6.h @@ -1,5 +1,5 @@ -#ifndef LINKER_HAND_L6_H -#define LINKER_HAND_L6_H +#ifndef LINKERHAND_L6_H +#define LINKERHAND_L6_H #include #include @@ -53,7 +53,7 @@ typedef enum static constexpr uint8_t TOUCH_TYPE_MATRIX = 0x02; // 矩阵型触觉类型值 static constexpr uint8_t TOUCH_PAGE_REQ = 0xC6; // 触觉分页读取的请求子命令 -class LinkerHand : public IHand +class LinkerHand : public linkerhand::hand::IHand { public: LinkerHand(uint32_t handId, const std::string &canChannel, int baudrate); @@ -143,4 +143,4 @@ class LinkerHand : public IHand std::string getErrorDescription(uint8_t error_code); }; } // namespace LinkerHandL6 -#endif // LINKER_HAND_L6_H +#endif // LINKERHAND_L6_H diff --git a/include/LinkerHandL7.h b/include/LinkerHandL7.h index eb23c9a..dbe4d59 100644 --- a/include/LinkerHandL7.h +++ b/include/LinkerHandL7.h @@ -1,5 +1,5 @@ -#ifndef LINKER_HAND_L7_H -#define LINKER_HAND_L7_H +#ifndef LINKERHAND_L7_H +#define LINKERHAND_L7_H #include #include @@ -45,7 +45,7 @@ typedef enum PALM_TOUCH = 0xB6 // 手掌指触觉传感 }FRAME_PROPERTY; -class LinkerHand : public IHand +class LinkerHand : public linkerhand::hand::IHand { public: LinkerHand(uint32_t handId, const std::string &canChannel, int baudrate); @@ -130,4 +130,4 @@ class LinkerHand : public IHand uint8_t sensor_type = 0; }; } // namespace LinkerHandL7 -#endif // LINKER_HAND_L7_H \ No newline at end of file +#endif // LINKERHAND_L7_H \ No newline at end of file diff --git a/include/Logger.h b/include/Logger.h new file mode 100644 index 0000000..84191b4 --- /dev/null +++ b/include/Logger.h @@ -0,0 +1,197 @@ +#ifndef LINKERHAND_LOGGER_H +#define LINKERHAND_LOGGER_H + +#include +#include +#include +#include +#include + +namespace linkerhand { +namespace logging { + +/** + * @brief 日志级别枚举 + */ +enum class LogLevel { + TRACE = 0, + DEBUG, + INFO, + WARN, + ERROR, + CRITICAL, + OFF +}; + +/** + * @brief 日志接口 + * + * 定义日志系统的接口,可以替换为 spdlog 或其他日志库 + */ +class ILogger { +public: + virtual ~ILogger() = default; + + virtual void log(LogLevel level, const std::string& message) = 0; + virtual void setLevel(LogLevel level) = 0; + virtual LogLevel getLevel() const = 0; + + void trace(const std::string& message) { log(LogLevel::TRACE, message); } + void debug(const std::string& message) { log(LogLevel::DEBUG, message); } + void info(const std::string& message) { log(LogLevel::INFO, message); } + void warn(const std::string& message) { log(LogLevel::WARN, message); } + void error(const std::string& message) { log(LogLevel::ERROR, message); } + void critical(const std::string& message) { log(LogLevel::CRITICAL, message); } +}; + +/** + * @brief 简单控制台日志实现 + * + * 使用 std::cout 和 std::cerr 输出日志 + * 可以后续替换为 spdlog + */ +class ConsoleLogger : public ILogger { +public: + explicit ConsoleLogger(LogLevel level = LogLevel::INFO) + : currentLevel_(level) {} + + void log(LogLevel level, const std::string& message) override { + if (level < currentLevel_ || level == LogLevel::OFF) { + return; + } + + std::lock_guard lock(mutex_); + + const char* levelStr = levelToString(level); + std::ostream& stream = (level >= LogLevel::ERROR) ? std::cerr : std::cout; + + stream << "[" << levelStr << "] " << message << std::endl; + } + + void setLevel(LogLevel level) override { + std::lock_guard lock(mutex_); + currentLevel_ = level; + } + + LogLevel getLevel() const override { + return currentLevel_; + } + +private: + static const char* levelToString(LogLevel level) { + switch (level) { + case LogLevel::TRACE: return "TRACE"; + case LogLevel::DEBUG: return "DEBUG"; + case LogLevel::INFO: return "INFO"; + case LogLevel::WARN: return "WARN"; + case LogLevel::ERROR: return "ERROR"; + case LogLevel::CRITICAL: return "CRITICAL"; + default: return "UNKNOWN"; + } + } + + LogLevel currentLevel_; + mutable std::mutex mutex_; +}; + +/** + * @brief 空日志实现(禁用日志) + */ +class NullLogger : public ILogger { +public: + void log(LogLevel, const std::string&) override {} + void setLevel(LogLevel) override {} + LogLevel getLevel() const override { return LogLevel::OFF; } +}; + +/** + * @brief 全局日志管理器 + */ +class Logger { +public: + /** + * @brief 获取默认日志实例 + */ + static ILogger& get() { + static std::unique_ptr instance = + std::make_unique(LogLevel::INFO); + return *instance; + } + + /** + * @brief 设置日志实例 + */ + static void setLogger(std::unique_ptr logger) { + static std::unique_ptr instance = std::move(logger); + get() = *instance; + } + + /** + * @brief 便捷方法:记录 TRACE 日志 + */ + static void trace(const std::string& message) { + get().trace(message); + } + + /** + * @brief 便捷方法:记录 DEBUG 日志 + */ + static void debug(const std::string& message) { + get().debug(message); + } + + /** + * @brief 便捷方法:记录 INFO 日志 + */ + static void info(const std::string& message) { + get().info(message); + } + + /** + * @brief 便捷方法:记录 WARN 日志 + */ + static void warn(const std::string& message) { + get().warn(message); + } + + /** + * @brief 便捷方法:记录 ERROR 日志 + */ + static void error(const std::string& message) { + get().error(message); + } + + /** + * @brief 便捷方法:记录 CRITICAL 日志 + */ + static void critical(const std::string& message) { + get().critical(message); + } + + /** + * @brief 设置日志级别 + */ + static void setLevel(LogLevel level) { + get().setLevel(level); + } + + /** + * @brief 获取日志级别 + */ + static LogLevel getLevel() { + return get().getLevel(); + } +}; + +} // namespace logging +} // namespace linkerhand + +// 便捷宏定义 +#define LINKERHAND_LOG_TRACE(msg) linkerhand::logging::Logger::trace(msg) +#define LINKERHAND_LOG_DEBUG(msg) linkerhand::logging::Logger::debug(msg) +#define LINKERHAND_LOG_INFO(msg) linkerhand::logging::Logger::info(msg) +#define LINKERHAND_LOG_WARN(msg) linkerhand::logging::Logger::warn(msg) +#define LINKERHAND_LOG_ERROR(msg) linkerhand::logging::Logger::error(msg) +#define LINKERHAND_LOG_CRITICAL(msg) linkerhand::logging::Logger::critical(msg) + +#endif // LINKERHAND_LOGGER_H diff --git a/include/ModBus.h b/include/ModBus.h index 5e99758..0c7472f 100644 --- a/include/ModBus.h +++ b/include/ModBus.h @@ -1,5 +1,5 @@ -#ifndef MOD_BUS_H -#define MOD_BUS_H +#ifndef LINKERHAND_MOD_BUS_H +#define LINKERHAND_MOD_BUS_H #if USE_RMAN #include #include @@ -20,9 +20,13 @@ #include "Common.h" #include "ICommunication.h" -namespace Communication //Communicator -{ - class ModBus : public ICommunication +namespace linkerhand { +namespace communication { + +/** + * @brief ModBus 通信实现 + */ +class ModBus : public ICommunication { public: ModBus(uint32_t handId); @@ -42,6 +46,11 @@ namespace Communication //Communicator std::mutex send_mutex; }; -} +} // namespace communication +} // namespace linkerhand + +// 向后兼容:在全局命名空间中提供别名 +namespace Communication = linkerhand::communication; + #endif -#endif // MOD_BUS_H +#endif // LINKERHAND_MOD_BUS_H diff --git a/include/ModbusLinkerHandL10.h b/include/ModbusLinkerHandL10.h index 74d3bbd..2da7ea4 100644 --- a/include/ModbusLinkerHandL10.h +++ b/include/ModbusLinkerHandL10.h @@ -1,5 +1,5 @@ -#ifndef MODBUS_L10_H -#define MODBUS_L10_H +#ifndef LINKERHAND_MODBUS_L10_H +#define LINKERHAND_MODBUS_L10_H #if USE_RMAN #include #include @@ -15,7 +15,7 @@ namespace ModbusLinkerHandL10 { -class LinkerHand : public IHand +class LinkerHand : public linkerhand::hand::IHand { public: LinkerHand(uint32_t handId); @@ -53,4 +53,4 @@ class LinkerHand : public IHand }; } #endif -#endif // MODBUS_L10_H +#endif // LINKERHAND_MODBUS_L10_H diff --git a/include/PCANBus.h b/include/PCANBus.h index c3221ba..1578308 100644 --- a/include/PCANBus.h +++ b/include/PCANBus.h @@ -1,6 +1,6 @@ #ifdef _WIN32 -#ifndef PCAN_BUS_H -#define PCAN_BUS_H +#ifndef LINKERHAND_PCAN_BUS_H +#define LINKERHAND_PCAN_BUS_H #include #include @@ -17,9 +17,13 @@ #include "ICanBus.h" -namespace Communication -{ - class PCANBus : public ICanBus +namespace linkerhand { +namespace communication { + +/** + * @brief Windows PCAN 总线实现 + */ +class PCANBus : public ICanBus { public: PCANBus(TPCANHandle channel, TPCANBaudrate bitrate, const LINKER_HAND linkerhand); @@ -43,6 +47,11 @@ namespace Communication std::chrono::steady_clock::time_point receive_last_time; std::queue send_queue; }; -} -#endif // PCAN_BUS_H +} // namespace communication +} // namespace linkerhand + +// 向后兼容:在全局命名空间中提供别名 +namespace Communication = linkerhand::communication; + +#endif // LINKERHAND_PCAN_BUS_H #endif diff --git a/include/RangeToArc.h b/include/RangeToArc.h index 5c1eb4b..11a936c 100644 --- a/include/RangeToArc.h +++ b/include/RangeToArc.h @@ -1,5 +1,5 @@ -#ifndef RANGE_TO_ARC_H -#define RANGE_TO_ARC_H +#ifndef LINKERHAND_RANGE_TO_ARC_H +#define LINKERHAND_RANGE_TO_ARC_H #include #include @@ -66,4 +66,4 @@ std::vector range_to_arc(const int &joints_type, const std::string &left std::vector arc_to_range(const int &joints_type, const std::string &left_or_right, const std::vector &hand_arc); -#endif // RANGE_TO_ARC_H +#endif // LINKERHAND_RANGE_TO_ARC_H diff --git a/script.sh b/script.sh index a77b8d3..044e69b 100755 --- a/script.sh +++ b/script.sh @@ -1,6 +1,11 @@ #!/bin/bash -VERSION="1.1.6" +# 从 CMakeLists.txt 读取版本号 +VERSION=$(grep -E "^\s*VERSION\s+" CMakeLists.txt | head -1 | sed 's/.*VERSION\s\+\([0-9.]*\).*/\1/') +if [ -z "$VERSION" ]; then + # 如果无法读取,使用默认版本 + VERSION="1.1.7" +fi # 确定系统架构 ARCH=$(uname -m) diff --git a/tests/unit/test_Common.cpp b/tests/unit/test_Common.cpp index 790614c..8194e2e 100644 --- a/tests/unit/test_Common.cpp +++ b/tests/unit/test_Common.cpp @@ -15,8 +15,8 @@ TEST(CommonTest, LinkerHandEnumValues) { // 测试 HAND_TYPE 枚举值 TEST(CommonTest, HandTypeEnumValues) { - EXPECT_EQ(LEFT, 0x28); - EXPECT_EQ(RIGHT, 0x27); + EXPECT_EQ(static_cast(LEFT), 0x28); + EXPECT_EQ(static_cast(RIGHT), 0x27); // 验证左右手类型不同 EXPECT_NE(LEFT, RIGHT); @@ -32,8 +32,8 @@ TEST(CommonTest, CommTypeEnumValues) { // 测试 Common 命名空间中的版本号 TEST(CommonTest, CurrentHandVersion) { - EXPECT_GT(Common::current_hand_version, 0.0f); - EXPECT_LE(Common::current_hand_version, 10.0f); // 合理的版本号范围 + EXPECT_GT(linkerhand::Common::current_hand_version, 0.0f); + EXPECT_LE(linkerhand::Common::current_hand_version, 10.0f); // 合理的版本号范围 } // 测试枚举值的类型转换 diff --git a/tests/unit/test_IHand_Utils.cpp b/tests/unit/test_IHand_Utils.cpp index 06238ab..1b0a715 100644 --- a/tests/unit/test_IHand_Utils.cpp +++ b/tests/unit/test_IHand_Utils.cpp @@ -5,7 +5,7 @@ #include // 创建一个测试用的 IHand 实现类 -class TestHand : public IHand { +class TestHand : public linkerhand::hand::IHand { public: void setJointPositions(const std::vector &jointAngles) override { (void)jointAngles;