diff --git a/cmvr-es/config/devices/dexhand/dexhand.pb.txt b/cmvr-es/config/devices/dexhand/dexhand.pb.txt index c1730107..8077edd6 100644 --- a/cmvr-es/config/devices/dexhand/dexhand.pb.txt +++ b/cmvr-es/config/devices/dexhand/dexhand.pb.txt @@ -1,4 +1,14 @@ dexhand { + dexhands { + id: "right_hand_ap001" + oymotion_ap001 { + can_interface: "can0" + hand_id: 2 + master_id: 1 + command_timeout_ms: 255 + } + } + dexhands { id: "hand1" rh56dftp { diff --git a/cmvr-es/config/manager/device_manager.pb.txt b/cmvr-es/config/manager/device_manager.pb.txt index 31147f1f..6bbd6cd6 100644 --- a/cmvr-es/config/manager/device_manager.pb.txt +++ b/cmvr-es/config/manager/device_manager.pb.txt @@ -59,6 +59,13 @@ device_manager { } + devices { + id: "right_hand_ap001" + type: DEVICE_TYPE_DEXHAND + config_file: "devices/dexhand/dexhand.pb.txt" + enable: true + } + devices { id: "hand2" type: DEVICE_TYPE_DEXHAND diff --git a/cmvr-es/config/manager/task_manager.pb.txt b/cmvr-es/config/manager/task_manager.pb.txt index 387eebcc..b9261829 100644 --- a/cmvr-es/config/manager/task_manager.pb.txt +++ b/cmvr-es/config/manager/task_manager.pb.txt @@ -27,6 +27,6 @@ task_manager { type: TASK_TYPE_QUIC_EDGE run_mode: TASK_RUN_MODE_BLOCKING_SERVICE config_file: "tasks/quic_edge_task/quic_edge_task.pb.txt" - enable: true + enable: false } } diff --git a/cmvr-es/devices/dexhand/CMakeLists.txt b/cmvr-es/devices/dexhand/CMakeLists.txt index f162ecd8..76393abd 100644 --- a/cmvr-es/devices/dexhand/CMakeLists.txt +++ b/cmvr-es/devices/dexhand/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(rh56dftp_dexhand) add_subdirectory(px_6ax_gen3) add_subdirectory(zero_sim_touch_dexhand) +add_subdirectory(oymotion_ap001) add_library(dexhand INTERFACE) @@ -11,6 +12,7 @@ target_link_libraries(dexhand cmvr_es::device::rh56dftp_dexhand cmvr_es::device::px_6ax_gen3 cmvr_es::device::zero_sim_touch_dexhand + cmvr_es::device::oymotion_ap001 cmvr_es::proto ) diff --git a/cmvr-es/devices/dexhand/dexhand_factory.h b/cmvr-es/devices/dexhand/dexhand_factory.h index de7ea7d9..b9fb8c60 100644 --- a/cmvr-es/devices/dexhand/dexhand_factory.h +++ b/cmvr-es/devices/dexhand/dexhand_factory.h @@ -11,6 +11,7 @@ #include "devices/dexhand/px_6ax_gen3/include/px_6ax_gen3.h" #include "devices/dexhand/rh56dftp_dexhand/include/rh56dftp_dexhand.h" #include "devices/dexhand/zero_sim_touch_dexhand/include/zero_sim_touch_dexhand.h" +#include "devices/dexhand/oymotion_ap001/include/oymotion_ap001.h" namespace cmvr::device { @@ -37,6 +38,10 @@ public: return std::make_shared( backendWithId_(cfg.id(), cfg.zero_sim_touch())); + case config::DexHandDeviceConfig::kOymotionAp001: + return std::make_shared( + backendWithId_(cfg.id(), cfg.oymotion_ap001())); + case config::DexHandDeviceConfig::BACKEND_NOT_SET: default: { diff --git a/cmvr-es/devices/dexhand/oymotion_ap001/CMakeLists.txt b/cmvr-es/devices/dexhand/oymotion_ap001/CMakeLists.txt new file mode 100644 index 00000000..5559d4c8 --- /dev/null +++ b/cmvr-es/devices/dexhand/oymotion_ap001/CMakeLists.txt @@ -0,0 +1,12 @@ +add_library(oymotion_ap001 STATIC src/oymotion_ap001.cpp) + +set(OHAND_SDK_ROOT "${PROJECT_SOURCE_DIR}/dependency/x86/third_party/ohand_serial_sdk") +add_library(ohand_serial_sdk STATIC IMPORTED) +set_target_properties(ohand_serial_sdk PROPERTIES + IMPORTED_LOCATION "${OHAND_SDK_ROOT}/lib/libROHSerialAPIStatic.a" + INTERFACE_INCLUDE_DIRECTORIES "${OHAND_SDK_ROOT}/include") + +target_include_directories(oymotion_ap001 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(oymotion_ap001 PRIVATE cmvr_es::hardware cmvr_es::proto ohand_serial_sdk pthread) + +add_library(cmvr_es::device::oymotion_ap001 ALIAS oymotion_ap001) diff --git a/cmvr-es/devices/dexhand/oymotion_ap001/include/oymotion_ap001.h b/cmvr-es/devices/dexhand/oymotion_ap001/include/oymotion_ap001.h new file mode 100644 index 00000000..2597949c --- /dev/null +++ b/cmvr-es/devices/dexhand/oymotion_ap001/include/oymotion_ap001.h @@ -0,0 +1,64 @@ +#ifndef CMVR_ES_OYMOTION_AP001_H +#define CMVR_ES_OYMOTION_AP001_H + +#include +#include +#include +#include + +#include "cmvr/config/dexhand_config/dexhand_config.pb.h" +#include "devices/dexhand/abstract_dexhand.h" + +namespace cmvr::device { + +class OYMotionAP001 final : public AbstractDexHand { +public: + static constexpr size_t MOTOR_COUNT = 6; + explicit OYMotionAP001(const config::OYMotionAP001Config& config); + ~OYMotionAP001() override; + std::string typeName() const override { return "OYMotionAP001"; } + bool init() override; + bool start() override; + bool stop() override; + Status state() const override; + std::string lastError() const override; + void getState(DexHandState& state) override; + void setAngles(const std::vector& values) override; + void setPositions(const std::vector& values) override; + void setVelocities(const std::vector& values) override; + void setForce(const std::vector& values) override; + void setTactilePollingRegions(const std::vector& regions) override; + std::vector getSensorData() override; + TactileRegionData getSensorData(FingerType finger, TactileRegion region) override; + ResultantForce getResultantForce(FingerType finger, TactileRegion region) override; + ForceNewtons getResultantForceNewtons(FingerType finger, TactileRegion region) override; + +private: + static uint32_t sdkMillis(); + static void sdkDelay(uint32_t milliseconds); + static void sdkSend(uint8_t address, uint8_t* data, uint8_t size, void* context); + static void sdkReceive(void* context); + static OYMotionAP001* fromSdkContext(void* context); + bool openSocket(); + bool checkSdkResult(uint8_t result, uint8_t remote_error, const char* operation); + void setFault(const std::string& message); + void setState(Status state); + std::array normalizedPositions(const std::vector& values, int maximum) const; + + config::OYMotionAP001Config config_; + std::string can_interface_; + uint8_t hand_id_{2}; + uint8_t master_id_{1}; + int socket_fd_{-1}; + void* sdk_context_{nullptr}; + mutable std::mutex state_mutex_; + mutable std::mutex io_mutex_; + Status lifecycle_state_{Status::CREATED}; + std::string last_error_; + std::array speeds_{{255, 255, 255, 255, 255, 255}}; + std::array current_positions_{}; + std::vector tactile_regions_; +}; + +} // namespace cmvr::device +#endif diff --git a/cmvr-es/devices/dexhand/oymotion_ap001/src/oymotion_ap001.cpp b/cmvr-es/devices/dexhand/oymotion_ap001/src/oymotion_ap001.cpp new file mode 100644 index 00000000..8496bf98 --- /dev/null +++ b/cmvr-es/devices/dexhand/oymotion_ap001/src/oymotion_ap001.cpp @@ -0,0 +1,166 @@ +#include "devices/dexhand/oymotion_ap001/include/oymotion_ap001.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "OHandSerialAPI.h" +#include "common/base/logging/logger.h" + +namespace cmvr::device { +namespace { +constexpr int kPositionInputMaximum = 2000; +constexpr int kAngleInputMaximum = 1000; +constexpr int kVelocityInputMaximum = 1000; +constexpr int kForceInputMaximum = 3000; +} + +OYMotionAP001::OYMotionAP001(const config::OYMotionAP001Config& config) : config_(config) { + id_ = config.id(); + can_interface_ = config.can_interface().empty() ? "can0" : config.can_interface(); + if (config.hand_id() > 0 && config.hand_id() <= 0xff) hand_id_ = static_cast(config.hand_id()); + if (config.master_id() > 0 && config.master_id() <= 0xff) master_id_ = static_cast(config.master_id()); +} + +OYMotionAP001::~OYMotionAP001() { stop(); } +uint32_t OYMotionAP001::sdkMillis() { + static const auto start = std::chrono::steady_clock::now(); + return static_cast(std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count()); +} +void OYMotionAP001::sdkDelay(uint32_t milliseconds) { std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); } +OYMotionAP001* OYMotionAP001::fromSdkContext(void* context) { return context ? *static_cast(context) : nullptr; } + +void OYMotionAP001::sdkSend(uint8_t address, uint8_t* data, uint8_t size, void* context) { + auto* self = fromSdkContext(context); + if (!self || self->socket_fd_ < 0) return; + for (uint8_t offset = 0; offset < size; offset += CAN_MAX_DLEN) { + can_frame frame{}; + frame.can_id = address; + frame.can_dlc = static_cast<__u8>(std::min(CAN_MAX_DLEN, size - offset)); + std::memcpy(frame.data, data + offset, frame.can_dlc); + if (write(self->socket_fd_, &frame, sizeof(frame)) != sizeof(frame)) { + self->setFault("[OYMotionAP001] failed to write CAN frame on " + self->can_interface_); + return; + } + } +} + +void OYMotionAP001::sdkReceive(void* context) { + auto* self = fromSdkContext(context); + if (!self || self->socket_fd_ < 0) return; + can_frame frame{}; + while (read(self->socket_fd_, &frame, sizeof(frame)) == sizeof(frame)) { + if ((frame.can_id & CAN_EFF_FLAG) || (frame.can_id & CAN_RTR_FLAG)) continue; + for (uint8_t i = 0; i < frame.can_dlc; ++i) HAND_OnData(context, frame.data[i]); + } +} + +bool OYMotionAP001::openSocket() { + socket_fd_ = socket(PF_CAN, SOCK_RAW, CAN_RAW); + if (socket_fd_ < 0) return false; + ifreq request{}; + std::strncpy(request.ifr_name, can_interface_.c_str(), IFNAMSIZ - 1); + if (ioctl(socket_fd_, SIOCGIFINDEX, &request) < 0) return false; + sockaddr_can address{}; + address.can_family = AF_CAN; + address.can_ifindex = request.ifr_ifindex; + if (bind(socket_fd_, reinterpret_cast(&address), sizeof(address)) < 0) return false; + const int flags = fcntl(socket_fd_, F_GETFL, 0); + return flags >= 0 && fcntl(socket_fd_, F_SETFL, flags | O_NONBLOCK) == 0; +} + +bool OYMotionAP001::init() { + std::lock_guard io_lock(io_mutex_); + if (sdk_context_) return true; + if (!openSocket()) { setFault("[OYMotionAP001] cannot open " + can_interface_ + "; ensure it is UP at 1 Mbps"); return false; } + HAND_SetTimerFunction(sdkMillis, sdkDelay); + sdk_context_ = HAND_CreateContext(this, HAND_PROTOCOL_UART, master_id_, sdkSend, sdkReceive); + if (!sdk_context_) { setFault("[OYMotionAP001] HAND_CreateContext failed"); return false; } + HAND_SetCommandTimeOut(sdk_context_, static_cast(config_.command_timeout_ms() > 0 ? std::min(config_.command_timeout_ms(), 65535) : 255)); + uint8_t major = 0, minor = 0, remote_error = 0; + if (!checkSdkResult(HAND_GetProtocolVersion(sdk_context_, hand_id_, &major, &minor, &remote_error), remote_error, "HAND_GetProtocolVersion")) return false; + CMVR_LOG(INFO) << "[OYMotionAP001] connected: id=" << id_ << ", interface=" << can_interface_ << ", hand_id=" << static_cast(hand_id_) << ", protocol=" << static_cast(major) << "." << static_cast(minor); + setState(Status::INITIALIZED); + return true; +} + +bool OYMotionAP001::start() { if (!init()) return false; setState(Status::STREAMING); return true; } +bool OYMotionAP001::stop() { + std::lock_guard io_lock(io_mutex_); + if (sdk_context_) { HAND_FreeContext(sdk_context_); sdk_context_ = nullptr; } + if (socket_fd_ >= 0) { close(socket_fd_); socket_fd_ = -1; } + if (state() != Status::FAULT) setState(Status::STOPPED); + return true; +} +AbstractDexHand::Status OYMotionAP001::state() const { std::lock_guard lock(state_mutex_); return lifecycle_state_; } +std::string OYMotionAP001::lastError() const { std::lock_guard lock(state_mutex_); return last_error_; } + +void OYMotionAP001::getState(DexHandState& output) { + DexHandState next{}; + next.is_initialized = state() == Status::INITIALIZED || state() == Status::STREAMING; + std::lock_guard io_lock(io_mutex_); + if (sdk_context_) { + std::array targets{}, positions{}; + uint8_t count = 0, remote_error = 0; + if (HAND_GetFingerPosAll(sdk_context_, hand_id_, targets.data(), positions.data(), &count, &remote_error) == HAND_RESP_SUCCESS) current_positions_ = positions; + } + for (size_t i = 0; i < MOTOR_COUNT; ++i) { + next.hands[i].position = static_cast(current_positions_[i]) * kPositionInputMaximum / 65535; + next.hands[i].angle = static_cast(current_positions_[i]) * kAngleInputMaximum / 65535; + next.hands[i].speed = static_cast(speeds_[i]) * kVelocityInputMaximum / 255; + } + const auto error = lastError(); + if (!error.empty()) next.hands[0].error_message.push_back(error); + output = std::move(next); +} + +std::array OYMotionAP001::normalizedPositions(const std::vector& values, int maximum) const { + if (values.size() != MOTOR_COUNT) throw std::invalid_argument("OYMotionAP001 expects exactly 6 values"); + std::array output{}; + for (size_t i = 0; i < MOTOR_COUNT; ++i) output[i] = static_cast(static_cast(std::clamp(values[i], 0, maximum)) * 65535U / maximum); + return output; +} + +void OYMotionAP001::setPositions(const std::vector& values) { + auto positions = normalizedPositions(values, kPositionInputMaximum); + std::lock_guard lock(io_mutex_); uint8_t remote_error = 0; + checkSdkResult(HAND_SetFingerPosAll(sdk_context_, hand_id_, positions.data(), speeds_.data(), MOTOR_COUNT, &remote_error), remote_error, "HAND_SetFingerPosAll"); +} +void OYMotionAP001::setAngles(const std::vector& values) { + auto positions = normalizedPositions(values, kAngleInputMaximum); + std::lock_guard lock(io_mutex_); uint8_t remote_error = 0; + checkSdkResult(HAND_SetFingerPosAll(sdk_context_, hand_id_, positions.data(), speeds_.data(), MOTOR_COUNT, &remote_error), remote_error, "HAND_SetFingerPosAll(angle normalization)"); +} +void OYMotionAP001::setVelocities(const std::vector& values) { + if (values.size() != MOTOR_COUNT) throw std::invalid_argument("OYMotionAP001 expects exactly 6 velocities"); + std::lock_guard lock(io_mutex_); + for (size_t i = 0; i < MOTOR_COUNT; ++i) speeds_[i] = static_cast(std::clamp(values[i], 0, kVelocityInputMaximum) * 255 / kVelocityInputMaximum); +} +void OYMotionAP001::setForce(const std::vector& values) { + if (values.size() != MOTOR_COUNT) throw std::invalid_argument("OYMotionAP001 expects exactly 6 force values"); + std::lock_guard lock(io_mutex_); + for (size_t i = 0; i < MOTOR_COUNT; ++i) { uint8_t remote_error = 0; if (!checkSdkResult(HAND_SetFingerForceTarget(sdk_context_, hand_id_, static_cast(i), static_cast(std::clamp(values[i], 0, kForceInputMaximum)), &remote_error), remote_error, "HAND_SetFingerForceTarget")) return; } +} + +void OYMotionAP001::setTactilePollingRegions(const std::vector& regions) { tactile_regions_ = regions; } +std::vector OYMotionAP001::getSensorData() { return {}; } +AbstractDexHand::TactileRegionData OYMotionAP001::getSensorData(FingerType, TactileRegion) { return {}; } +AbstractDexHand::ResultantForce OYMotionAP001::getResultantForce(FingerType, TactileRegion) { return {}; } +AbstractDexHand::ForceNewtons OYMotionAP001::getResultantForceNewtons(FingerType, TactileRegion) { return {}; } + +bool OYMotionAP001::checkSdkResult(uint8_t result, uint8_t remote_error, const char* operation) { + if (result == HAND_RESP_SUCCESS) return true; + setFault("[OYMotionAP001] " + std::string(operation) + " failed: result=" + std::to_string(result) + ", remote_error=" + std::to_string(remote_error)); + return false; +} +void OYMotionAP001::setFault(const std::string& message) { { std::lock_guard lock(state_mutex_); lifecycle_state_ = Status::FAULT; last_error_ = message; } CMVR_LOG(ERROR) << message; } +void OYMotionAP001::setState(Status next) { std::lock_guard lock(state_mutex_); lifecycle_state_ = next; if (next == Status::INITIALIZED || next == Status::STREAMING) last_error_.clear(); } +} // namespace cmvr::device diff --git a/dependency/x86/third_party/ohand_serial_sdk/include/OHandSerialAPI.h b/dependency/x86/third_party/ohand_serial_sdk/include/OHandSerialAPI.h new file mode 100644 index 00000000..e58c6818 --- /dev/null +++ b/dependency/x86/third_party/ohand_serial_sdk/include/OHandSerialAPI.h @@ -0,0 +1,1016 @@ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __HAND_SERIAL_API_H__ +#define __HAND_SERIAL_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +#include + + +/* Exported types ------------------------------------------------------------*/ + +#ifndef NULL +#define NULL ((void*)0) +#endif + +#ifndef BOOL +#define BOOL uint8_t +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + + +/* Exported constants --------------------------------------------------------*/ + +#define MAX_THUMB_ROOT_POS 3 +#define MAX_MOTOR_CNT 6 +#define MAX_FORCE_ENTRIES 12 * 5 /* Max force entries for one finger */ + + +typedef enum +{ + HAND_PROTOCOL_UART, + HAND_PROTOCOL_I2C +} HAND_PROTOCOL; + + +#define PROTOCOL_VERSION_MAJOR 3 + + +/* + * OHand error codes + */ + +/* + * Error codes for remote peer, protocol part + */ +#define ERR_PROTOCOL_WRONG_LRC 0x01 + + +/* + * Error codes for remote peer, command part + */ +#define ERR_COMMAND_INVALID 0x11 +#define ERR_COMMAND_INVALID_BYTE_COUNT 0x12 +#define ERR_COMMAND_INVALID_DATA 0x13 + + +/* + * Error codes for remote peer, status part + */ +#define ERR_STATUS_INIT 0x21 +#define ERR_STATUS_CALI 0x22 +#define ERR_STATUS_STUCK 0x23 + + +/* + * Error codes for remote peer, operation result part + */ +#define ERR_OP_FAILED 0x31 +#define ERR_SAVE_FAILED 0x32 + + +/* + * API return values + */ +#define HAND_RESP_HAND_ERROR 0xFF /* device error, error call back will be called with OHand error codes listed above */ + +#define HAND_RESP_SUCCESS 0x00 +#define HAND_RESP_TIMER_FUNC_NOT_SET 0x01 /* local error, timer function not set, call HAND_SetTimerFunction(...) first */ +#define HAND_RESP_INVALID_CONTEXT 0x02 /* local error, invalid context, NULL or send data function not set */ +#define HAND_RESP_TIMEOUT 0x03 /* local error, time out when waiting node response */ +#define HAND_RESP_INVALID_OUT_BUFFER_SIZE 0x04 /* local error, out buffer size not matched to returned data */ +#define HAND_RESP_UNMATCHED_ADDR 0x05 /* local error, unmatched node id between returned and waiting */ +#define HAND_RESP_UNMATCHED_CMD 0x06 /* local error, unmatched command between returned and waiting */ +#define HAND_RESP_DATA_SIZE_TOO_BIG 0x07 /* local error, size of data to send exceeds the buffer size */ +#define HAND_RESP_DATA_INVALID 0x08 /* local error, data content invalid */ + + +/* Sub-command for HAND_CMD_SET_CUSTOM */ +#define SUB_CMD_SET_SPEED (1 << 0) +#define SUB_CMD_SET_POS (1 << 1) +#define SUB_CMD_SET_ANGLE (1 << 2) +#define SUB_CMD_GET_POS (1 << 3) +#define SUB_CMD_GET_ANGLE (1 << 4) +#define SUB_CMD_GET_CURRENT (1 << 5) +#define SUB_CMD_GET_FORCE (1 << 6) +#define SUB_CMD_GET_STATUS (1 << 7) + + +/* Exported macro ------------------------------------------------------------*/ + + + +/* Exported functions ------------------------------------------------------- */ + +/* + * OHand Serial API + */ + +/** + * @brief Create context and set master address, send data function and receive data function + * @note For none interrupt receive function, pass receive function pointer as parameter + * RecvDataImpl and call HAND_OnData(...) in receive function. For interrupt receive + * mode, pass NULL as parameter RecvDataImpl and call HAND_OnData(...) in ISR. Call + * this before using other get & set functions + * @param ctx_private_data: Context private data, e.g., address of serial port instance, + * port name string, etc. Resource should be available during runtime. + * @param protocol: HAND_PROTOCOL_UART or HAND_PROTOCOL_I2C + * @param address_master: master node address + * @param SendDataImpl: send data function pointer + * @param RecvDataImpl: receive data function pointer, NULL for interrupt receive mode + * @retval Context + */ +void *HAND_CreateContext( + const void *ctx_private_data, + HAND_PROTOCOL protocol, + uint8_t address_master, + void (*SendDataImpl)(uint8_t addr, uint8_t *data, uint8_t size, void *ctx), + void (*RecvDataImpl)(void *ctx) +); + + +/** + * @brief Free OHand context + * @param ctx: pointer to OHand context + * @retval None + */ +void HAND_FreeContext(void *ctx); + + +/** + * @brief Set timer related function + * @note Call this before using get & set functions + * @param GetMilliSecondsImpl: pointer of function to get miliseconds + * @param DelayMilliSecondsImpl: pointer of function to delay miliseconds + * @retval None + */ +void HAND_SetTimerFunction(uint32_t (*GetMilliSecondsImpl)(void), void (*DelayMilliSecondsImpl)(uint32_t ms)); + + +/** + * @brief Get current tick of system in milliseconds + * @note if HAND_SetTimerFunction(...) is not set, this will always return 0 + * @param None + * @retval None + */ +uint32_t HAND_GetTick(void); + + +/** + * @brief Set command timeout value + * @note Call this before using get & set functions. Default value is 255ms + * @param ctx: pointer to OHand context + * @param timeout: timeout in miliseconds + * @param DelayMilliSecondsImpl: pointer of function to delay miliseconds + * @retval None + */ +void HAND_SetCommandTimeOut(void *ctx, uint16_t timeout); + + +/** + * @brief Feed data to internal parser + * @note Call this in data receive function, either RecvDataImpl or ISR + * @param ctx: pointer to OHand context + * @param data: data byte received + * @retval None + */ +void HAND_OnData(void *ctx, uint8_t data); + + + +/* + * Gets + */ + +/** + * @brief Get protocol version + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param major: pointer to uint8_t type var, when success, the major version of firmware will be stored + * @param minor: pointer to uint8_t type var, when success, the minor version of firmware will be stored + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetProtocolVersion(void *ctx, uint8_t hand_id, uint8_t *major, uint8_t *minor, uint8_t *remote_err); + +/** + * @brief Get firmware version + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param major: pointer to uint8_t type var, when success, the major version of firmware will be stored + * @param minor: pointer to uint8_t type var, when success, the minor version of firmware will be stored + * @param revision: pointer to uint16_t type var, when success, the revision of firmware will be stored + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFirmwareVersion(void *ctx, uint8_t hand_id, uint8_t *major, uint8_t *minor, uint16_t *revision, uint8_t *remote_err); + + +/** + * @brief Get hardware version + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param hw_type: pointer to uint8_t type var, when success, the hardware type will be stored + * @param hw_ver: pointer to uint8_t type var, when success, the hardware version will be stored + * @param boot_version: pointer to uint16_t type var, when success, the major version will be stored in high byte, + * while the minor ver in the low byte + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetHardwareVersion(void *ctx, uint8_t hand_id, uint8_t *hw_type, uint8_t *hw_ver, uint16_t *boot_version, uint8_t *remote_err); + + +/** + * @brief Get calibration data + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param end_pos: address of array to put end_pos + * @param start_pos: address of array to put start_pos + * @param motor_cnt: motor count, i.e., array size of end_pos[] or start_pos[] + * @param thumb_root_pos: address of array to put thumb_root_pos + * @param thumb_root_pos_cnt: count of pre-defined thumb root pos + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetCaliData(void *ctx, uint8_t hand_id, uint16_t *end_pos, uint16_t *start_pos, uint8_t *motor_cnt, uint16_t *thumb_root_pos, uint8_t *thumb_root_pos_cnt, uint8_t *remote_err); + + +/** + * @brief Get PID gain + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param p: address of var to put PID gain p + * @param i: address of var to put PID gain i + * @param d: address of var to put PID gain d + * @param g: address of var to put PID gain g + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerPID(void *ctx, uint8_t hand_id, uint8_t finger_id, float *p, float *i, float *d, float *g, uint8_t *remote_err); + +/** + * @brief Get Stop Parameter + * @note + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param speed: address of var to put Stop Parameter speed + * @param current: address of var to put Stop Parameter current + * @param after_period: address of var to put Stop Parameter after_period + * @param retry_period: address of var to put Stop Parameter retry_period + * @retval -RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerStopParam(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t *speed, uint16_t *current, uint16_t *after_period, uint16_t *retry_period, uint8_t *remote_err); + +/** + * @brief Get current limit of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param current_limit: address of var to put current limit in mA + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerCurrentLimit(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t *current_limit, uint8_t *remote_err); + + +/** + * @brief Get current of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param current: address of var to put current in mA + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerCurrent(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t *current, uint8_t *remote_err); + + +/** + * @brief Get target force of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param force_target: address of var to put force target in mN + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerForceTarget(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t *force_target, uint8_t *remote_err); + + +/** + * @brief Get force of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: actually sensor id + * @param force_entry_cnt: count of force entries + * @param force: address of var to put force, may be multi-point forces, or normal force, tangential force and dir + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerForce(void *ctx, uint8_t hand_id, uint8_t finger_id, uint8_t *force_entry_cnt, uint8_t *force, uint8_t *remote_err); + + +/** + * @brief Get absolute position limit of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: id of finger + * @param low_limit: address of var to put low limit of finger position + * @param high_limit: address of var to put high limit of finger position + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerPosLimit(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t *low_limit, uint16_t *high_limit, uint8_t *remote_err); + + +/** + * @brief Get absolute position of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: id of finger + * @param target_pos: address of var to put raw target position, i.e., encoder value of finger + * @param current_pos: address of var to put raw current position, i.e., encoder value of finger + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerPosAbs(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t *target_pos, uint16_t *current_pos, uint8_t *remote_err); + + +/** + * @brief Get logical position of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: id of finger + * @param target_pos: address of var to put logical target position + * @param current_pos: address of var to put logical current position + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerPos(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t *target_pos, uint16_t *current_pos, uint8_t *remote_err); + + +/** + * @brief Get angle of finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: id of finger + * @param target_angle: address of var to put logical target position, value = real angle * 100 + * @param current_angle: address of var to put logical current position, value = real angle * 100 + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerAngle(void *ctx, uint8_t hand_id, uint8_t finger_id, int16_t *target_angle, int16_t *current_angle, uint8_t *remote_err); + + +/** + * @brief Get position of thumb's root + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param raw_encoder: address of var to put raw encoder value of thumb's root, value range [0-65535] + * @param pos: address of var to put mapped position of thumb's root, value range [0-2], or 255 if invalid + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetThumbRootPos(void *ctx, uint8_t hand_id, uint16_t *raw_encoder, uint8_t *pos, uint8_t *remote_err); + + +/** + * @brief Get absolute position of all fingers + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param motor_cnt: number of motors + * @param target_pos: address of var to put raw target position, i.e., encoder value of finger + * @param current_pos: address of var to put raw current position, i.e., encoder value of finger + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerPosAbsAll(void *ctx, uint8_t hand_id, uint16_t *target_pos, uint16_t *current_pos, uint8_t *motor_cnt, uint8_t *remote_err); + + +/** + * @brief Get logical position of all fingers + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param target_pos: address of var to put logical target position + * @param current_pos: address of var to put logical current position + * @param motor_cnt: number of motors + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerPosAll(void *ctx, uint8_t hand_id, uint16_t *target_pos, uint16_t *current_pos, uint8_t *motor_cnt, uint8_t *remote_err); + + +/** + * @brief Get first joint angle of all fingers + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param target_angle: address of var to put target angle + * @param current_pos: address of var to put current angle + * @param motor_cnt: number of motors + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerAngleAll(void *ctx, uint8_t hand_id, int16_t *target_angle, int16_t *current_angle, uint8_t *motor_cnt, uint8_t *remote_err); + + + +/** + * @brief Get self test level + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param self_test_on: address of var to put self-test level + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetSelfTestLevel(void *ctx, uint8_t hand_id, uint8_t *self_test_level, uint8_t *remote_err); + + +/** + * @brief Get beep switch + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param beep_on: address of var to put beep switch status + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetBeepSwitch(void *ctx, uint8_t hand_id, uint8_t *beep_switch, uint8_t *remote_err); + + +/** + * @brief Get button pressed count of OHand + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param pressed_cnt: button pressed count + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetButtonPressedCnt(void *ctx, uint8_t hand_id, uint8_t *pressed_cnt, uint8_t *remote_err); + + +/** + * @brief Get the 96 bits device UID + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param uid_w0: pointer to word 0 of UID + * @param uid_w1: pointer to word 1 of UID + * @param uid_w2: pointer to word 2 of UID + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetUID(void *ctx, uint8_t hand_id, uint32_t *uid_w0, uint32_t *uid_w1, uint32_t *uid_w2, uint8_t *remote_err); + + +/** + * @brief Get battery voltage + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param voltage: pointer to uint16_t type var, when success, the voltage in mv will be stored + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetBatteryVoltage(void *ctx, uint8_t hand_id, uint16_t *voltage, uint8_t *remote_err); + + +/** + * @brief Get usage stat + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param total_use_time: address of var to put total use time in seconds + * @param total_open_times: address of array to put total_open_times[5] + * @param motor_cnt: motor count, i.e., array size of total_use_time[] or total_open_times[] + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetUsageStat(void *ctx, uint8_t hand_id, uint32_t *total_use_time, uint32_t *total_open_times, uint8_t motor_cnt, uint8_t *remote_err); + + +/** + * @brief Get manufacture data + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param data: pointer to array to put manufacture data + * @param data_size: address of var to put manufacture data size + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetManufactureData(void *ctx, uint8_t hand_id, uint8_t *data, uint8_t *data_size, uint8_t *remote_err); + + +/** + * @brief Get vendor id + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param vendor_id: address of var to put vendor id + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetVendorID(void *ctx, uint8_t hand_id, uint16_t *vendor_id, uint8_t *remote_err); + + +/** + * @brief Get force PID gain + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param p: address of var to put PID gain p + * @param i: address of var to put PID gain i + * @param d: address of var to put PID gain d + * @param g: address of var to put PID gain g + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetForcePID(void *ctx, uint8_t hand_id, uint8_t finger_id, float *p, float *i, float *d, float *g, uint8_t *remote_err); + +/** + * @brief Get Speed Control Parameters of finger + * @note + * @param hand_id: id of OHand + * @param brake_distance: Speed Brake Distance + * @param accel_distance: Speed Accelerate Distance + * @param speed_ratio: PID Speed Ratio + * @retval -RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_GetFingerSpeedCtrlParams(void *ctx, uint8_t hand_id, uint16_t *brake_distance, uint16_t *accel_distance, float *speed_ratio, uint8_t* remote_err); + + +/* + * Sets + */ + + /** + * @brief Reset hand + * @note NO response, so return code must be timeout + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param mode: 0 boot to user code, 1 boot to DFU mode + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_Reset(void *ctx, uint8_t hand_id, uint8_t mode, uint8_t *remote_err); + + + /** + * @brief Turn hand off + * @note NO response, so return code must be timeout + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_PowerOff(void *ctx, uint8_t hand_id, uint8_t *remote_err); + + +/** + * @brief Set hand id + * @note Need to reboot device after setting + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param new_id: new id for hand + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetID(void *ctx, uint8_t hand_id, uint8_t new_id, uint8_t *remote_err); + + +/** + * @brief Start calibration + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param key: key to enable calibration, to avoid mishandling + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_Calibrate(void *ctx, uint8_t hand_id, uint16_t key, uint8_t *remote_err); + + +/** + * @brief Set calibration data + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param end_pos: address of array to put end_pos + * @param start_pos: address of array to put start_pos + * @param motor_cnt: motor count, i.e., array size of end_pos[] or start_pos[] + * @param thumb_root_pos: address of array to put thumb_root_pos + * @param thumb_root_pos_cnt: count of pre-defined thumb root pos + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetCaliData(void *ctx, uint8_t hand_id, uint16_t *end_pos, uint16_t *start_pos, uint8_t motor_cnt, uint16_t *thumb_root_pos, uint8_t thumb_root_pos_cnt, uint8_t *remote_err); + + +/** + * @brief Set PID gain + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param p: PID gain p + * @param i: PID gain i + * @param d: PID gain d + * @param d: PID gain g + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerPID(void *ctx, uint8_t hand_id, uint8_t finger_id, float p, float i, float d, float g, uint8_t *remote_err); + + +/** + * @brief Set finger current limit + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param current_limit: current limit in mA for finger + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerCurrentLimit(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t current_limit, uint8_t *remote_err); + + +/** + * @brief Set finger normal force target + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param force_target: force target in mN for finger + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerForceTarget(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t force_target, uint8_t *remote_err); + + +/** + * @brief Set limit of absolute position for finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: id of finger + * @param low_limit: low limit of absolute position + * @param high_limit: high limit of absolute position + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerPosLimit(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t low_limit, uint16_t high_limit, uint8_t *remote_err); + + +/** + * @brief Start finger in case of stuck. + * @note Fingers will auto start after about 500ms when stuck. + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id_bits: bits of fingers to start + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_FingerStart(void *ctx, uint8_t hand_id, uint8_t finger_id_bits, uint8_t *remote_err); + + +/** + * @brief Stop finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id_bits: bits of fingers to stop + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_FingerStop(void *ctx, uint8_t hand_id, uint8_t finger_id_bits, uint8_t *remote_err); + + +/** + * @brief Set absolute position for finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: id of finger + * @param raw_pos: raw position of finger + * @param speed: moving speed, [0, 255], 255 means move full range in 1 second + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerPosAbs(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t raw_pos, uint8_t speed, uint8_t *remote_err); + + +/** + * @brief Move finger to position + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger to move + * @param pos: target position, [0, 65535], mapped to [low_limit, high_limit] internally + * @param speed: moving speed, [0, 255], 255 means move full range in 1s (0.7s for thumb root) + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerPos(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t pos, uint8_t speed, uint8_t *remote_err); + +/** + * @brief Set finger angle + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger to move + * @param angle: target angle, value = real angle * 100 + * @param speed: moving speed, [0, 255], 255 means move full range in 1s (0.7s for thumb root) + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerAngle(void *ctx, uint8_t hand_id, uint8_t finger_id, int16_t angle, uint8_t speed, uint8_t *remote_err); + + +/** + * @brief Set thumb root pos + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param pos: 0, 1 or 2 + * @param speed: moving speed, [0, 255], 255 means move full range in 0.7s + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetThumbRootPos(void *ctx, uint8_t hand_id, uint8_t pos, uint8_t speed, uint8_t *remote_err); + + +/** + * @brief Set absolute positions for all fingers + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param raw_pos: raw position of finger + * @param speed: moving speed, [0, 255], 255 means move full range in 1 second + * @param motor_cnt: motor count, i.e., array size of raw_pos[] or speed[] + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerPosAbsAll(void *ctx, uint8_t hand_id, uint16_t *raw_pos, uint8_t *speed, uint8_t motor_cnt, uint8_t *remote_err); + + +/** + * @brief Move all fingers to specified position + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param pos: target position, [0, 65535], mapped to [low_limit, high_limit] internally + * @param speed: moving speed, [0, 255], 255 means move full range in 1 second + * @param motor_cnt: motor count, i.e., array size of pos[] or speed[] + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerPosAll(void *ctx, uint8_t hand_id, uint16_t *pos, uint8_t *speed, uint8_t motor_cnt, uint8_t *remote_err); + + +/** + * @brief Set first joint angles for all fingers + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param angle: target angle, value = real angle * 100 + * @param speed: moving speed, [0, 255], 255 means move full range in 1 second + * @param motor_cnt: motor count, i.e., array size of angle[] or speed[] + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerAngleAll(void *ctx, uint8_t hand_id, int16_t *angle, uint8_t *speed, uint8_t motor_cnt, uint8_t *remote_err); + + +/** + * @brief Custom command + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param data: address of data + * @param send_data_size: send data size + * @param recv_data_size: address of recv data size + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetCustom(void *ctx, uint8_t hand_id, uint8_t* data, uint8_t send_data_size, uint8_t *recv_data_size, uint8_t *remote_err); + + +/** + * @brief Set self-test level + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param self_test_level: self-test level, 0: wait for command HAND_CMD_START_INIT to init; 1: semi self-test on power up; 2: full self-test on power up + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetSelfTestLevel(void *ctx, uint8_t hand_id, uint8_t self_test_level, uint8_t *remote_err); + + +/** + * @brief Set beep ON/OFF + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param beep_on: beep on/off + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetBeepSwitch(void *ctx, uint8_t hand_id, uint8_t beep_on, uint8_t *remote_err); + + +/** + * @brief Beep + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param duration: beep duration in milliseconds + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_Beep(void *ctx, uint8_t hand_id, uint16_t duration, uint8_t *remote_err); + + +/** + * @brief Set button pressed count, usually used when calibrating robotic hand + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param pressed_cnt: button pressed count + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetButtonPressedCnt(void *ctx, uint8_t hand_id, uint8_t pressed_cnt, uint8_t *remote_err); + + + /** + * @brief Start init in case of SELF_TEST_SWITCH=0 + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_StartInit(void *ctx, uint8_t hand_id, uint8_t *remote_err); + + + /** + * @brief Set manufacture data + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param data: address of data + * @param data_size: data size + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetManufactureData(void *ctx, uint8_t hand_id, uint8_t *data, uint8_t data_size, uint8_t *remote_err); + + +/** + * @brief Set force PID for specific finger + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param p: PID gain p + * @param i: PID gain i + * @param d: PID gain d + * @param d: PID gain g + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerForcePID(void *ctx, uint8_t hand_id, uint8_t finger_id, float p, float i, float d, float g, uint8_t *remote_err); + +/** + * @brief Set Stop Parameter + * @note + * @param hand_id: id of OHand + * @param finger_id: index of finger + * @param speed: address of var to put Stop Parameter speed + * @param current: address of var to put Stop Parameter current + * @param after_period: address of var to put Stop Parameter after_period + * @param retry_period: address of var to put Stop Parameter retry_period + * @retval -RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerStopParam(void *ctx, uint8_t hand_id, uint8_t finger_id, uint16_t speed, uint16_t current, uint16_t after_period, uint16_t retry_period, uint8_t *remote_err); + + +/** + * @brief Set Speed Control Parameters of finger + * @note + * @param hand_id: id of OHand + * @param brake_distance: Speed Brake Distance + * @param accel_distance: Speed Accelerate Distance + * @param speed_ratio: PID Speed Ratio + * @retval -RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_SetFingerSpeedCtrlParams(void *ctx, uint8_t hand_id, uint16_t brake_distance, uint16_t accel_distance, float speed_ratio, uint8_t* remote_err); + + +/** + * @brief Reset force, that is, calibrate + * @note + * @param ctx: pointer to OHand context + * @param hand_id: id of OHand + * @param remote_err: address to put remote node error in case of HAND_RESP_HAND_ERROR + * @retval -HAND_RESP_SUCCESS: success + * -Others: failed, see definition of API return values + */ +uint8_t HAND_ResetForce(void *ctx, uint8_t hand_id, uint8_t *remote_err); + +#ifdef __cplusplus +} +#endif +#endif //__HAND_SERIAL_API_H__ diff --git a/dependency/x86/third_party/ohand_serial_sdk/lib/libROHSerialAPIStatic.a b/dependency/x86/third_party/ohand_serial_sdk/lib/libROHSerialAPIStatic.a new file mode 100644 index 00000000..8d805a5a Binary files /dev/null and b/dependency/x86/third_party/ohand_serial_sdk/lib/libROHSerialAPIStatic.a differ diff --git a/protos/cmvr/config/dexhand_config/dexhand_config.proto b/protos/cmvr/config/dexhand_config/dexhand_config.proto index 1568aa3e..210d1801 100644 --- a/protos/cmvr/config/dexhand_config/dexhand_config.proto +++ b/protos/cmvr/config/dexhand_config/dexhand_config.proto @@ -45,6 +45,14 @@ message ZeroSimTouchDexHand { string id = 1; } +message OYMotionAP001Config { + string id = 1; + string can_interface = 2; + uint32 hand_id = 3; + uint32 master_id = 4; + uint32 command_timeout_ms = 5; +} + message DexHandDeviceConfig { @@ -55,6 +63,7 @@ message DexHandDeviceConfig { RH56DFTPDexHandConfig rh56dftp = 10; PX6AXGen3 px_6ax_gen3 = 11; ZeroSimTouchDexHand zero_sim_touch = 12; + OYMotionAP001Config oymotion_ap001 = 13; } }