diff --git a/include/dynamixel_sdk/dynamixel_sdk.h b/include/dynamixel_sdk/dynamixel_sdk.h new file mode 100644 index 0000000..9e3bc7f --- /dev/null +++ b/include/dynamixel_sdk/dynamixel_sdk.h @@ -0,0 +1,34 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file that includes whole Dynamixel SDK libraries +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_DYNAMIXELSDK_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_DYNAMIXELSDK_H_ + + +#include "group_bulk_read.h" +#include "group_bulk_write.h" +#include "group_sync_read.h" +#include "group_sync_write.h" +#include "packet_handler.h" +#include "port_handler.h" + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_DYNAMIXELSDK_H_ */ diff --git a/include/dynamixel_sdk/group_bulk_read.h b/include/dynamixel_sdk/group_bulk_read.h new file mode 100644 index 0000000..624c00d --- /dev/null +++ b/include/dynamixel_sdk/group_bulk_read.h @@ -0,0 +1,167 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for Dynamixel Bulk Read +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPBULKREAD_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPBULKREAD_H_ + + +#include +#include +#include "port_handler.h" +#include "packet_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for reading multiple Dynamixel data from different addresses with different lengths at once +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC GroupBulkRead +{ + private: + PortHandler *port_; + PacketHandler *ph_; + + std::vector id_list_; + std::map address_list_; // + std::map length_list_; // + std::map data_list_; // + std::map error_list_; // + + bool last_result_; + bool is_param_changed_; + + uint8_t *param_; + + void makeParam(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that Initializes instance for Bulk Read + /// @param port PortHandler instance + /// @param ph PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + GroupBulkRead(PortHandler *port, PacketHandler *ph); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls clearParam function to clear the parameter list for Bulk Read + //////////////////////////////////////////////////////////////////////////////// + ~GroupBulkRead() { clearParam(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PortHandler instance + /// @return PortHandler instance + //////////////////////////////////////////////////////////////////////////////// + PortHandler *getPortHandler() { return port_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PacketHandler instance + /// @return PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + PacketHandler *getPacketHandler() { return ph_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that adds id, start_address, data_length to the Bulk Read list + /// @param id Dynamixel ID + /// @param start_address Address of the data for read + /// @data_length Length of the data for read + /// @return false + /// @return when the ID exists already in the list + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool addParam (uint8_t id, uint16_t start_address, uint16_t data_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that removes id from the Bulk Read list + /// @param id Dynamixel ID + //////////////////////////////////////////////////////////////////////////////// + void removeParam (uint8_t id); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the Bulk Read list + //////////////////////////////////////////////////////////////////////////////// + void clearParam (); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits the Bulk Read instruction packet which might be constructed by GroupBulkRead::addParam function + /// @return COMM_NOT_AVAILABLE + /// @return when the list for Bulk Read is empty + /// @return or the other communication results which come from PacketHandler::bulkReadTx + //////////////////////////////////////////////////////////////////////////////// + int txPacket(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives the packet which might be come from the Dynamixel + /// @return COMM_NOT_AVAILABLE + /// @return when the list for Bulk Read is empty + /// @return COMM_RX_FAIL + /// @return when there is no packet recieved + /// @return COMM_SUCCESS + /// @return when there is packet recieved + /// @return or the other communication results + //////////////////////////////////////////////////////////////////////////////// + int rxPacket(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits and receives the packet which might be come from the Dynamixel + /// @return COMM_RX_FAIL + /// @return when there is no packet recieved + /// @return COMM_SUCCESS + /// @return when there is packet recieved + /// @return or the other communication results which come from GroupBulkRead::txPacket or GroupBulkRead::rxPacket + //////////////////////////////////////////////////////////////////////////////// + int txRxPacket(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks whether there are available data which might be received by GroupBulkRead::rxPacket or GroupBulkRead::txRxPacket + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param data_length Length of the data for read + /// @return false + /// @return when there are no data available + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool isAvailable (uint8_t id, uint16_t address, uint16_t data_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets the data which might be received by GroupBulkRead::rxPacket or GroupBulkRead::txRxPacket + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @data_length Length of the data for read + /// @return data value + //////////////////////////////////////////////////////////////////////////////// + uint32_t getData (uint8_t id, uint16_t address, uint16_t data_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets the error which might be received by GroupBulkRead::rxPacket or GroupBulkRead::txRxPacket + /// @param id Dynamixel ID + /// @error error of Dynamixel + /// @return true + /// @return when Dynamixel returned specific error byte + /// @return or false + //////////////////////////////////////////////////////////////////////////////// + bool getError (uint8_t id, uint8_t* error); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPBULKREAD_H_ */ diff --git a/include/dynamixel_sdk/group_bulk_write.h b/include/dynamixel_sdk/group_bulk_write.h new file mode 100644 index 0000000..f3c2af2 --- /dev/null +++ b/include/dynamixel_sdk/group_bulk_write.h @@ -0,0 +1,127 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for Dynamixel Bulk Write +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPBULKWRITE_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPBULKWRITE_H_ + + +#include +#include +#include "port_handler.h" +#include "packet_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for writing multiple Dynamixel data from different addresses with different lengths at once +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC GroupBulkWrite +{ + private: + PortHandler *port_; + PacketHandler *ph_; + + std::vector id_list_; + std::map address_list_; // + std::map length_list_; // + std::map data_list_; // + + bool is_param_changed_; + + uint8_t *param_; + uint16_t param_length_; + + void makeParam(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that Initializes instance for Bulk Write + /// @param port PortHandler instance + /// @param ph PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + GroupBulkWrite(PortHandler *port, PacketHandler *ph); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls clearParam function to clear the parameter list for Bulk Write + //////////////////////////////////////////////////////////////////////////////// + ~GroupBulkWrite() { clearParam(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PortHandler instance + /// @return PortHandler instance + //////////////////////////////////////////////////////////////////////////////// + PortHandler *getPortHandler() { return port_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PacketHandler instance + /// @return PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + PacketHandler *getPacketHandler() { return ph_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that adds id, start_address, data_length to the Bulk Write list + /// @param id Dynamixel ID + /// @param start_address Address of the data for write + /// @param data_length Length of the data for write + /// @return false + /// @return when the ID exists already in the list + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool addParam (uint8_t id, uint16_t start_address, uint16_t data_length, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that removes id from the Bulk Write list + /// @param id Dynamixel ID + //////////////////////////////////////////////////////////////////////////////// + void removeParam (uint8_t id); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that changes the data for write in id -> start_address -> data_length to the Bulk Write list + /// @param id Dynamixel ID + /// @param start_address Address of the data for write + /// @param data_length Length of the data for write + /// @param data for replacement + /// @return false + /// @return when the ID doesn't exist in the list + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool changeParam (uint8_t id, uint16_t start_address, uint16_t data_length, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the Bulk Write list + //////////////////////////////////////////////////////////////////////////////// + void clearParam (); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits the Bulk Write instruction packet which might be constructed by GroupBulkWrite::addParam function + /// @return COMM_NOT_AVAILABLE + /// @return when the list for Bulk Write is empty + /// @return when Protocol1.0 has been used + /// @return or the other communication results which come from PacketHandler::bulkWriteTxOnly + //////////////////////////////////////////////////////////////////////////////// + int txPacket(); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPBULKWRITE_H_ */ diff --git a/include/dynamixel_sdk/group_sync_read.h b/include/dynamixel_sdk/group_sync_read.h new file mode 100644 index 0000000..0b934f6 --- /dev/null +++ b/include/dynamixel_sdk/group_sync_read.h @@ -0,0 +1,171 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for Dynamixel Sync Read +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPSYNCREAD_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPSYNCREAD_H_ + + +#include +#include +#include "port_handler.h" +#include "packet_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for reading multiple Dynamixel data from same address with same length at once +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC GroupSyncRead +{ + private: + PortHandler *port_; + PacketHandler *ph_; + + std::vector id_list_; + std::map data_list_; // + std::map error_list_; // + + bool last_result_; + bool is_param_changed_; + + uint8_t *param_; + uint16_t start_address_; + uint16_t data_length_; + + void makeParam(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that Initializes instance for Sync Read + /// @param port PortHandler instance + /// @param ph PacketHandler instance + /// @param start_address Address of the data for read + /// @param data_length Length of the data for read + //////////////////////////////////////////////////////////////////////////////// + GroupSyncRead(PortHandler *port, PacketHandler *ph, uint16_t start_address, uint16_t data_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls clearParam function to clear the parameter list for Sync Read + //////////////////////////////////////////////////////////////////////////////// + ~GroupSyncRead() { clearParam(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PortHandler instance + /// @return PortHandler instance + //////////////////////////////////////////////////////////////////////////////// + PortHandler *getPortHandler() { return port_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PacketHandler instance + /// @return PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + PacketHandler *getPacketHandler() { return ph_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that adds id, start_address, data_length to the Sync Read list + /// @param id Dynamixel ID + /// @return false + /// @return when the ID exists already in the list + /// @return when the protocol1.0 has been used + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool addParam (uint8_t id); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that removes id from the Sync Read list + /// @param id Dynamixel ID + //////////////////////////////////////////////////////////////////////////////// + void removeParam (uint8_t id); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the Sync Read list + //////////////////////////////////////////////////////////////////////////////// + void clearParam (); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits the Sync Read instruction packet which might be constructed by GroupSyncRead::addParam function + /// @return COMM_NOT_AVAILABLE + /// @return when the list for Sync Read is empty + /// @return when the protocol1.0 has been used + /// @return or the other communication results which come from PacketHandler::syncReadTx + //////////////////////////////////////////////////////////////////////////////// + int txPacket(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives the packet which might be come from the Dynamixel + /// @return COMM_NOT_AVAILABLE + /// @return when the list for Sync Read is empty + /// @return when the protocol1.0 has been used + /// @return COMM_SUCCESS + /// @return when there is packet recieved + /// @return or the other communication results + //////////////////////////////////////////////////////////////////////////////// + int rxPacket(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits and receives the packet which might be come from the Dynamixel + /// @return COMM_NOT_AVAILABLE + /// @return when the protocol1.0 has been used + /// @return COMM_RX_FAIL + /// @return when there is no packet recieved + /// @return COMM_SUCCESS + /// @return when there is packet recieved + /// @return or the other communication results which come from GroupBulkRead::txPacket or GroupBulkRead::rxPacket + //////////////////////////////////////////////////////////////////////////////// + int txRxPacket(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks whether there are available data which might be received by GroupSyncRead::rxPacket or GroupSyncRead::txRxPacket + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param data_length Length of the data for read + /// @return false + /// @return when there are no data available + /// @return when the protocol1.0 has been used + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool isAvailable (uint8_t id, uint16_t address, uint16_t data_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets the data which might be received by GroupSyncRead::rxPacket or GroupSyncRead::txRxPacket + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @data_length Length of the data for read + /// @return data value + //////////////////////////////////////////////////////////////////////////////// + uint32_t getData (uint8_t id, uint16_t address, uint16_t data_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets the error which might be received by GroupSyncRead::rxPacket or GroupSyncRead::txRxPacket + /// @param id Dynamixel ID + /// @error error of Dynamixel + /// @return true + /// @return when Dynamixel returned specific error byte + /// @return or false + //////////////////////////////////////////////////////////////////////////////// + bool getError (uint8_t id, uint8_t* error); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPSYNCREAD_H_ */ diff --git a/include/dynamixel_sdk/group_sync_write.h b/include/dynamixel_sdk/group_sync_write.h new file mode 100644 index 0000000..81f5e8c --- /dev/null +++ b/include/dynamixel_sdk/group_sync_write.h @@ -0,0 +1,124 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for Dynamixel Sync Write +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPSYNCWRITE_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPSYNCWRITE_H_ + + +#include +#include +#include "port_handler.h" +#include "packet_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for writing multiple Dynamixel data from same address with same length at once +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC GroupSyncWrite +{ + private: + PortHandler *port_; + PacketHandler *ph_; + + std::vector id_list_; + std::map data_list_; // + + bool is_param_changed_; + + uint8_t *param_; + uint16_t start_address_; + uint16_t data_length_; + + void makeParam(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that Initializes instance for Sync Write + /// @param port PortHandler instance + /// @param ph PacketHandler instance + /// @param start_address Address of the data for write + /// @param data_length Length of the data for write + //////////////////////////////////////////////////////////////////////////////// + GroupSyncWrite(PortHandler *port, PacketHandler *ph, uint16_t start_address, uint16_t data_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls clearParam function to clear the parameter list for Sync Write + //////////////////////////////////////////////////////////////////////////////// + ~GroupSyncWrite() { clearParam(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PortHandler instance + /// @return PortHandler instance + //////////////////////////////////////////////////////////////////////////////// + PortHandler *getPortHandler() { return port_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PacketHandler instance + /// @return PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + PacketHandler *getPacketHandler() { return ph_; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that adds id, start_address, data_length to the Sync Write list + /// @param id Dynamixel ID + /// @param data Data for write + /// @return false + /// @return when the ID exists already in the list + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool addParam (uint8_t id, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that removes id from the Sync Write list + /// @param id Dynamixel ID + //////////////////////////////////////////////////////////////////////////////// + void removeParam (uint8_t id); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that changes the data for write in id -> start_address -> data_length to the Sync Write list + /// @param id Dynamixel ID + /// @param data for replacement + /// @return false + /// @return when the ID doesn't exist in the list + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool changeParam (uint8_t id, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the Sync Write list + //////////////////////////////////////////////////////////////////////////////// + void clearParam (); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits the Sync Write instruction packet which might be constructed by GroupSyncWrite::addParam function + /// @return COMM_NOT_AVAILABLE + /// @return when the list for Sync Write is empty + /// @return or the other communication results which come from PacketHandler::syncWriteTxOnly + //////////////////////////////////////////////////////////////////////////////// + int txPacket(); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_GROUPSYNCWRITE_H_ */ diff --git a/include/dynamixel_sdk/packet_handler.h b/include/dynamixel_sdk/packet_handler.h new file mode 100644 index 0000000..a2efc99 --- /dev/null +++ b/include/dynamixel_sdk/packet_handler.h @@ -0,0 +1,595 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for Dynamixel packet control +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PACKETHANDLER_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PACKETHANDLER_H_ + +#if defined(ARDUINO) || defined(__OPENCR__) || defined(__OPENCM904__) +#include + +#define ERROR_PRINT SerialBT2.print +#else +#define ERROR_PRINT printf + +#endif + +#include +#include +#include "port_handler.h" + +#define BROADCAST_ID 0xFE // 254 +#define MAX_ID 0xFC // 252 + +/* Macro for Control Table Value */ +#define DXL_MAKEWORD(a, b) ((uint16_t)(((uint8_t)(((uint64_t)(a)) & 0xff)) | ((uint16_t)((uint8_t)(((uint64_t)(b)) & 0xff))) << 8)) +#define DXL_MAKEDWORD(a, b) ((uint32_t)(((uint16_t)(((uint64_t)(a)) & 0xffff)) | ((uint32_t)((uint16_t)(((uint64_t)(b)) & 0xffff))) << 16)) +#define DXL_LOWORD(l) ((uint16_t)(((uint64_t)(l)) & 0xffff)) +#define DXL_HIWORD(l) ((uint16_t)((((uint64_t)(l)) >> 16) & 0xffff)) +#define DXL_LOBYTE(w) ((uint8_t)(((uint64_t)(w)) & 0xff)) +#define DXL_HIBYTE(w) ((uint8_t)((((uint64_t)(w)) >> 8) & 0xff)) + +/* Instruction for DXL Protocol */ +#define INST_PING 1 +#define INST_READ 2 +#define INST_WRITE 3 +#define INST_REG_WRITE 4 +#define INST_ACTION 5 +#define INST_FACTORY_RESET 6 +#define INST_SYNC_WRITE 131 // 0x83 +#define INST_BULK_READ 146 // 0x92 +// --- Only for 2.0 --- // +#define INST_REBOOT 8 +#define INST_CLEAR 16 // 0x10 +#define INST_STATUS 85 // 0x55 +#define INST_SYNC_READ 130 // 0x82 +#define INST_BULK_WRITE 147 // 0x93 + +// Communication Result +#define COMM_SUCCESS 0 // tx or rx packet communication success +#define COMM_PORT_BUSY -1000 // Port is busy (in use) +#define COMM_TX_FAIL -1001 // Failed transmit instruction packet +#define COMM_RX_FAIL -1002 // Failed get status packet +#define COMM_TX_ERROR -2000 // Incorrect instruction packet +#define COMM_RX_WAITING -3000 // Now recieving status packet +#define COMM_RX_TIMEOUT -3001 // There is no status packet +#define COMM_RX_CORRUPT -3002 // Incorrect status packet +#define COMM_NOT_AVAILABLE -9000 // + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class that inherits Protocol1PacketHandler class or Protocol2PacketHandler class +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC PacketHandler +{ + protected: + PacketHandler() { } + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns PacketHandler instance + /// @return PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + static PacketHandler *getPacketHandler(float protocol_version = 2.0); + + virtual ~PacketHandler() { } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns Protocol version + /// @return protocol version + //////////////////////////////////////////////////////////////////////////////// + virtual float getProtocolVersion() = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets description of communication result + /// @param result Communication result which might be gotten by the tx rx functions + /// @return description of communication result in const char* (string) + //////////////////////////////////////////////////////////////////////////////// + virtual const char *getTxRxResult (int result) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets description of hardware error + /// @param error Dynamixel hardware error which might be gotten by the tx rx functions + /// @return description of hardware error in const char* (string) + //////////////////////////////////////////////////////////////////////////////// + virtual const char *getRxPacketError (uint8_t error) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits the instruction packet txpacket via PortHandler port. + /// @description The function clears the port buffer by PortHandler::clearPort() function, + /// @description then transmits txpacket by PortHandler::writePort() function. + /// @description The function activates only when the port is not busy and when the packet is already written on the port buffer + /// @param port PortHandler instance + /// @param txpacket packet for transmission + /// @return COMM_PORT_BUSY + /// @return when the port is already in use + /// @return COMM_TX_ERROR + /// @return when txpacket is out of range described by TXPACKET_MAX_LEN + /// @return COMM_TX_FAIL + /// @return when written packet is shorter than expected + /// @return or COMM_SUCCESS + //////////////////////////////////////////////////////////////////////////////// + virtual int txPacket (PortHandler *port, uint8_t *txpacket) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives packet (rxpacket) during designated time via PortHandler port + /// @description The function repeatedly tries to receive rxpacket by PortHandler::readPort() function. + /// @description It breaks out + /// @description when PortHandler::isPacketTimeout() shows the timeout, + /// @description when rxpacket seemed as corrupted, or + /// @description when nothing received + /// @param port PortHandler instance + /// @param rxpacket received packet + /// @return COMM_RX_CORRUPT + /// @return when it received the packet but it couldn't find header in the packet + /// @return when it found header in the packet but the id, length or error value is out of range + /// @return when it received the packet but it is shorted than expected + /// @return COMM_RX_TIMEOUT + /// @return when there is no rxpacket received until PortHandler::isPacketTimeout() shows the timeout + /// @return COMM_SUCCESS + /// @return when rxpacket passes checksum test + /// @return or COMM_RX_FAIL + //////////////////////////////////////////////////////////////////////////////// + virtual int rxPacket (PortHandler *port, uint8_t *rxpacket) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits packet (txpacket) and receives packet (rxpacket) during designated time via PortHandler port + /// @description The function calls PacketHandler::txPacket(), + /// @description and calls PacketHandler::rxPacket() if it succeeds PacketHandler::txPacket(). + /// @description It breaks out + /// @description when it fails PacketHandler::txPacket(), + /// @description when txpacket is called by PacketHandler::broadcastPing() / PacketHandler::syncWriteTxOnly() / PacketHandler::regWriteTxOnly / PacketHandler::action + /// @param port PortHandler instance + /// @param txpacket packet for transmission + /// @param rxpacket received packet + /// @return COMM_SUCCESS + /// @return when it succeeds PacketHandler::txPacket() and PacketHandler::rxPacket() + /// @return or the other communication results which come from PacketHandler::txPacket() and PacketHandler::rxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int txRxPacket (PortHandler *port, uint8_t *txpacket, uint8_t *rxpacket, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that pings Dynamixel but doesn't take its model number + /// @description The function calls PacketHandler::ping() which gets Dynamixel model number, + /// @description but doesn't carry the model number + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::ping() + //////////////////////////////////////////////////////////////////////////////// + virtual int ping (PortHandler *port, uint8_t id, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that pings Dynamixel and takes its model number + /// @description The function makes an instruction packet with INST_PING, + /// @description transmits the packet with PacketHandler::txRxPacket(), + /// @description and call PacketHandler::readTxRx to read model_number in the rx buffer. + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return COMM_SUCCESS + /// @return when it succeeds to ping Dynamixel and get model_number from it + /// @return or the other communication results which come from PacketHandler::txRxPacket() and PacketHandler::readTxRx() + //////////////////////////////////////////////////////////////////////////////// + virtual int ping (PortHandler *port, uint8_t id, uint16_t *model_number, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only in Protocol 2.0) The function that pings all connected Dynamixel + /// @param port PortHandler instance + /// @param id_list ID list of Dynamixels which are found by broadcast ping + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + virtual int broadcastPing (PortHandler *port, std::vector &id_list) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixels run as written in the Dynamixel register + /// @description The function makes an instruction packet with INST_ACTION, + /// @description transmits the packet with PacketHandler::txRxPacket(). + /// @description To use this function, Dynamixel register should be set by PacketHandler::regWriteTxOnly() or PacketHandler::regWriteTxRx() + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int action (PortHandler *port, uint8_t id) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixel reboot + /// @description The function makes an instruction packet with INST_REBOOT, + /// @description transmits the packet with PacketHandler::txRxPacket(), + /// @description then Dynamixel reboots. + /// @description During reboot, its LED will blink. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + virtual int reboot (PortHandler *port, uint8_t id, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that reset multi-turn revolution information of Dynamixel + /// @description The function makes an instruction packet with INST_CLEAR, + /// @description transmits the packet with PacketHandler::txRxPacket(). + /// @description Applied Products : MX with Protocol 2.0 (Firmware v42 or above), + /// @description Dynamixel X-series (Firmware v42 or above). + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int clearMultiTurn (PortHandler *port, uint8_t id, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixel reset as it was produced in the factory + /// @description The function makes an instruction packet with INST_FACTORY_RESET, + /// @description transmits the packet with PacketHandler::txRxPacket(). + /// @description Be careful of the use. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param option Reset option + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int factoryReset (PortHandler *port, uint8_t id, uint8_t option = 0, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_READ instruction packet + /// @description The function makes an instruction packet with INST_READ, + /// @description transmits the packet with PacketHandler::txPacket(). + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return or the other communication results which come from PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int readTx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives the packet and reads the data in the packet + /// @description The function receives the packet which might be come by previous INST_READ instruction packet transmission, + /// @description gets the data from the packet. + /// @param port PortHandler instance + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::rxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int readRx (PortHandler *port, uint8_t id, uint16_t length, uint8_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_READ instruction packet, and read data from received packet + /// @description The function makes an instruction packet with INST_READ, + /// @description transmits and receives the packet with PacketHandler::txRxPacket(), + /// @description gets the data from the packet. + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return or the other communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int readTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readTx() function for reading 1 byte data + /// @description The function calls PacketHandler::readTx() function for reading 1 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + virtual int read1ByteTx (PortHandler *port, uint8_t id, uint16_t address) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readRx() function and reads 1 byte data on the packet + /// @description The function calls PacketHandler::readRx() function, + /// @description gets 1 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + virtual int read1ByteRx (PortHandler *port, uint8_t id, uint8_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readTxRx() function for reading 1 byte data + /// @description The function calls PacketHandler::readTxRx(), + /// @description gets 1 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int read1ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint8_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readTx() function for reading 2 byte data + /// @description The function calls PacketHandler::readTx() function for reading 2 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + virtual int read2ByteTx (PortHandler *port, uint8_t id, uint16_t address) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readRx() function and reads 2 byte data on the packet + /// @description The function calls PacketHandler::readRx() function, + /// @description gets 2 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + virtual int read2ByteRx (PortHandler *port, uint8_t id, uint16_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readTxRx() function for reading 2 byte data + /// @description The function calls PacketHandler::readTxRx(), + /// @description gets 2 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int read2ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readTx() function for reading 4 byte data + /// @description The function calls PacketHandler::readTx() function for reading 4 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + virtual int read4ByteTx (PortHandler *port, uint8_t id, uint16_t address) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readRx() function and reads 4 byte data on the packet + /// @description The function calls PacketHandler::readRx() function, + /// @description gets 4 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + virtual int read4ByteRx (PortHandler *port, uint8_t id, uint32_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::readTxRx() function for reading 4 byte data + /// @description The function calls PacketHandler::readTxRx(), + /// @description gets 4 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int read4ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint32_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_WRITE instruction packet with the data for write + /// @description The function makes an instruction packet with INST_WRITE and the data for write, + /// @description transmits the packet with PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @return communication results which come from PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int writeTxOnly (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_WRITE instruction packet with the data for write, and receives the packet + /// @description The function makes an instruction packet with INST_WRITE and the data for write, + /// @description transmits and receives the packet with PacketHandler::txRxPacket(), + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int writeTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::writeTxOnly() for writing 1 byte data + /// @description The function calls PacketHandler::writeTxOnly() for writing 1 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + virtual int write1ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint8_t data) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::writeTxRx() for writing 1 byte data and receives the packet + /// @description The function calls PacketHandler::writeTxRx() for writing 1 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + virtual int write1ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint8_t data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::writeTxOnly() for writing 2 byte data + /// @description The function calls PacketHandler::writeTxOnly() for writing 2 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + virtual int write2ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint16_t data) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::writeTxRx() for writing 2 byte data and receives the packet + /// @description The function calls PacketHandler::writeTxRx() for writing 2 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + virtual int write2ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::writeTxOnly() for writing 4 byte data + /// @description The function calls PacketHandler::writeTxOnly() for writing 4 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + virtual int write4ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint32_t data) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls PacketHandler::writeTxRx() for writing 4 byte data and receives the packet + /// @description The function calls PacketHandler::writeTxRx() for writing 4 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + virtual int write4ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint32_t data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_REG_WRITE instruction packet with the data for writing on the Dynamixel register + /// @description The function makes an instruction packet with INST_REG_WRITE and the data for writing on the Dynamixel register, + /// @description transmits the packet with PacketHandler::txPacket(). + /// @description The data written in the register will act when INST_ACTION instruction packet is transmitted to the Dynamxel. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @return communication results which come from PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int regWriteTxOnly (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_REG_WRITE instruction packet with the data for writing on the Dynamixel register, and receives the packet + /// @description The function makes an instruction packet with INST_REG_WRITE and the data for writing on the Dynamixel register, + /// @description transmits and receives the packet with PacketHandler::txRxPacket(), + /// @description gets the error from the packet. + /// @description The data written in the register will act when INST_ACTION instruction packet is transmitted to the Dynamxel. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int regWriteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_SYNC_READ instruction packet + /// @description The function makes an instruction packet with INST_SYNC_READ, + /// @description transmits the packet with PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param start_address Address of the data for Sync Read + /// @param data_length Length of the data for Sync Read + /// @param param Parameter for Sync Read + /// @param param_length Length of the data for Sync Read + /// @return communication results which come from PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int syncReadTx (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length) = 0; + // SyncReadRx -> GroupSyncRead class + // SyncReadTxRx -> GroupSyncRead class + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_SYNC_WRITE instruction packet + /// @description The function makes an instruction packet with INST_SYNC_WRITE, + /// @description transmits the packet with PacketHandler::txRxPacket(). + /// @param port PortHandler instance + /// @param start_address Address of the data for Sync Write + /// @param data_length Length of the data for Sync Write + /// @param param Parameter for Sync Write + /// @param param_length Length of the data for Sync Write + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int syncWriteTxOnly (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_BULK_READ instruction packet + /// @description The function makes an instruction packet with INST_BULK_READ, + /// @description transmits the packet with PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param param Parameter for Bulk Read + /// @param param_length Length of the data for Bulk Read + /// @return communication results which come from PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int bulkReadTx (PortHandler *port, uint8_t *param, uint16_t param_length) = 0; + // BulkReadRx -> GroupBulkRead class + // BulkReadTxRx -> GroupBulkRead class + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_BULK_WRITE instruction packet + /// @description The function makes an instruction packet with INST_BULK_WRITE, + /// @description transmits the packet with PacketHandler::txRxPacket(). + /// @param port PortHandler instance + /// @param param Parameter for Bulk Write + /// @param param_length Length of the data for Bulk Write + /// @return communication results which come from PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + virtual int bulkWriteTxOnly (PortHandler *port, uint8_t *param, uint16_t param_length) = 0; +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PACKETHANDLER_H_ */ diff --git a/include/dynamixel_sdk/port_handler.h b/include/dynamixel_sdk/port_handler.h new file mode 100644 index 0000000..63976c0 --- /dev/null +++ b/include/dynamixel_sdk/port_handler.h @@ -0,0 +1,177 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for port control +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PORTHANDLER_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PORTHANDLER_H_ + +#if defined(__linux__) +#define WINDECLSPEC +#elif defined(__APPLE__) +#define WINDECLSPEC +#elif defined(_WIN32) || defined(_WIN64) + #ifdef WINDLLEXPORT + #define WINDECLSPEC __declspec(dllexport) + #else + #define WINDECLSPEC __declspec(dllimport) + #endif +#elif defined(ARDUINO) || defined(__OPENCR__) || defined(__OPENCM904__) +#define WINDECLSPEC +#endif + +#ifdef __GNUC__ +#define DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +#define DEPRECATED __declspec(deprecated) +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define DEPRECATED +#endif + +#include + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for port control that inherits PortHandlerLinux, PortHandlerWindows, PortHandlerMac, or PortHandlerArduino +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC PortHandler +{ + public: + static const int DEFAULT_BAUDRATE_ = 57600; ///< Default Baudrate + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets PortHandler class inheritance + /// @description The function gets class inheritance (PortHandlerLinux / PortHandlerWindows / PortHandlerMac / PortHandlerArduino. + //////////////////////////////////////////////////////////////////////////////// + static PortHandler *getPortHandler(const char *port_name); + + bool is_using_; ///< shows whether the port is in use + + virtual ~PortHandler() { } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that opens the port + /// @description The function calls PortHandlerLinux::setBaudRate() to open the port. + /// @return communication results which come from PortHandlerLinux::setBaudRate() + //////////////////////////////////////////////////////////////////////////////// + virtual bool openPort() = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function closes the port. + //////////////////////////////////////////////////////////////////////////////// + virtual void closePort() = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the port + /// @description The function clears the port. + //////////////////////////////////////////////////////////////////////////////// + virtual void clearPort() = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets port name into the port handler + /// @description The function sets port name into the port handler. + /// @param port_name Port name + //////////////////////////////////////////////////////////////////////////////// + virtual void setPortName(const char* port_name) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns port name set into the port handler + /// @description The function returns current port name set into the port handler. + /// @return Port name + //////////////////////////////////////////////////////////////////////////////// + virtual char *getPortName() = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets baudrate into the port handler + /// @description The function sets baudrate into the port handler. + /// @param baudrate Baudrate + /// @return false + /// @return when error was occurred during port opening + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + virtual bool setBaudRate(const int baudrate) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns current baudrate set into the port handler + /// @description The function returns current baudrate set into the port handler. + /// @return Baudrate + //////////////////////////////////////////////////////////////////////////////// + virtual int getBaudRate() = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks how much bytes are able to be read from the port buffer + /// @description The function checks how much bytes are able to be read from the port buffer + /// @description and returns the number. + /// @return Length of read-able bytes in the port buffer + //////////////////////////////////////////////////////////////////////////////// + virtual int getBytesAvailable() = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that reads bytes from the port buffer + /// @description The function gets bytes from the port buffer, + /// @description and returns a number of bytes read. + /// @param packet Buffer for the packet received + /// @param length Length of the buffer for read + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes read + //////////////////////////////////////////////////////////////////////////////// + virtual int readPort(uint8_t *packet, int length) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that writes bytes on the port buffer + /// @description The function writes bytes on the port buffer, + /// @description and returns a number of bytes which are successfully written. + /// @param packet Buffer which would be written on the port buffer + /// @param length Length of the buffer for write + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes written + //////////////////////////////////////////////////////////////////////////////// + virtual int writePort(uint8_t *packet, int length) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with packet_length. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + virtual void setPacketTimeout(uint16_t packet_length) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with msec. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + virtual void setPacketTimeout(double msec) = 0; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks whether packet timeout is occurred + /// @description The function checks whether current time is passed by the time of packet timeout from the time set by PortHandlerLinux::setPacketTimeout(). + //////////////////////////////////////////////////////////////////////////////// + virtual bool isPacketTimeout() = 0; +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PORTHANDLER_H_ */ diff --git a/include/dynamixel_sdk/port_handler_arduino.h b/include/dynamixel_sdk/port_handler_arduino.h new file mode 100644 index 0000000..78ddea9 --- /dev/null +++ b/include/dynamixel_sdk/port_handler_arduino.h @@ -0,0 +1,183 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for port control in Arduino +/// @author Cho (Hancheol Cho), Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_ARDUINO_PORTHANDLERARDUINO_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_ARDUINO_PORTHANDLERARDUINO_H_ + +#if defined(ARDUINO) || defined(__OPENCR__) || defined (__OPENCM904__) +#include +#endif + +#include "port_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for control port in Arduino +//////////////////////////////////////////////////////////////////////////////// +class PortHandlerArduino : public PortHandler +{ + private: + int socket_fd_; + int baudrate_; + char port_name_[100]; + + double packet_start_time_; + double packet_timeout_; + double tx_time_per_byte; + +#if defined(__OPENCM904__) + UARTClass *p_dxl_serial; +#endif + + bool setupPort(const int cflag_baud); + + double getCurrentTime(); + double getTimeSinceStart(); + + int checkBaudrateAvailable(int baudrate); + + void setPowerOn(); + void setPowerOff(); + void setTxEnable(); + void setTxDisable(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that initializes instance of PortHandler and gets port_name + /// @description The function initializes instance of PortHandler and gets port_name. + //////////////////////////////////////////////////////////////////////////////// + PortHandlerArduino(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function calls PortHandlerArduino::closePort() to close the port. + //////////////////////////////////////////////////////////////////////////////// + virtual ~PortHandlerArduino() { closePort(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that opens the port + /// @description The function calls PortHandlerArduino::setBaudRate() to open the port. + /// @return communication results which come from PortHandlerArduino::setBaudRate() + //////////////////////////////////////////////////////////////////////////////// + bool openPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function closes the port. + //////////////////////////////////////////////////////////////////////////////// + void closePort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the port + /// @description The function clears the port. + //////////////////////////////////////////////////////////////////////////////// + void clearPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets port name into the port handler + /// @description The function sets port name into the port handler. + /// @param port_name Port name + //////////////////////////////////////////////////////////////////////////////// + void setPortName(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns port name set into the port handler + /// @description The function returns current port name set into the port handler. + /// @return Port name + //////////////////////////////////////////////////////////////////////////////// + char *getPortName(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets baudrate into the port handler + /// @description The function sets baudrate into the port handler. + /// @param baudrate Baudrate + /// @return false + /// @return when error was occurred during port opening + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool setBaudRate(const int baudrate); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns current baudrate set into the port handler + /// @description The function returns current baudrate set into the port handler. + /// @return Baudrate + //////////////////////////////////////////////////////////////////////////////// + int getBaudRate(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks how much bytes are able to be read from the port buffer + /// @description The function checks how much bytes are able to be read from the port buffer + /// @description and returns the number. + /// @return Length of read-able bytes in the port buffer + //////////////////////////////////////////////////////////////////////////////// + int getBytesAvailable(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that reads bytes from the port buffer + /// @description The function gets bytes from the port buffer, + /// @description and returns a number of bytes read. + /// @param packet Buffer for the packet received + /// @param length Length of the buffer for read + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes read + //////////////////////////////////////////////////////////////////////////////// + int readPort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that writes bytes on the port buffer + /// @description The function writes bytes on the port buffer, + /// @description and returns a number of bytes which are successfully written. + /// @param packet Buffer which would be written on the port buffer + /// @param length Length of the buffer for write + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes written + //////////////////////////////////////////////////////////////////////////////// + int writePort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with packet_length. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(uint16_t packet_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with msec. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(double msec); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks whether packet timeout is occurred + /// @description The function checks whether current time is passed by the time of packet timeout from the time set by PortHandlerArduino::setPacketTimeout(). + //////////////////////////////////////////////////////////////////////////////// + bool isPacketTimeout(); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_ARDUINO_PORTHANDLERARDUINO_H_ */ diff --git a/include/dynamixel_sdk/port_handler_linux.h b/include/dynamixel_sdk/port_handler_linux.h new file mode 100644 index 0000000..a690e43 --- /dev/null +++ b/include/dynamixel_sdk/port_handler_linux.h @@ -0,0 +1,171 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for port control in Linux +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_LINUX_PORTHANDLERLINUX_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_LINUX_PORTHANDLERLINUX_H_ + + +#include "port_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for control port in Linux +//////////////////////////////////////////////////////////////////////////////// +class PortHandlerLinux : public PortHandler +{ + private: + int socket_fd_; + int baudrate_; + char port_name_[100]; + + double packet_start_time_; + double packet_timeout_; + double tx_time_per_byte; + + bool setupPort(const int cflag_baud); + bool setCustomBaudrate(int speed); + int getCFlagBaud(const int baudrate); + + double getCurrentTime(); + double getTimeSinceStart(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that initializes instance of PortHandler and gets port_name + /// @description The function initializes instance of PortHandler and gets port_name. + //////////////////////////////////////////////////////////////////////////////// + PortHandlerLinux(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function calls PortHandlerLinux::closePort() to close the port. + //////////////////////////////////////////////////////////////////////////////// + virtual ~PortHandlerLinux() { closePort(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that opens the port + /// @description The function calls PortHandlerLinux::setBaudRate() to open the port. + /// @return communication results which come from PortHandlerLinux::setBaudRate() + //////////////////////////////////////////////////////////////////////////////// + bool openPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function closes the port. + //////////////////////////////////////////////////////////////////////////////// + void closePort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the port + /// @description The function clears the port. + //////////////////////////////////////////////////////////////////////////////// + void clearPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets port name into the port handler + /// @description The function sets port name into the port handler. + /// @param port_name Port name + //////////////////////////////////////////////////////////////////////////////// + void setPortName(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns port name set into the port handler + /// @description The function returns current port name set into the port handler. + /// @return Port name + //////////////////////////////////////////////////////////////////////////////// + char *getPortName(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets baudrate into the port handler + /// @description The function sets baudrate into the port handler. + /// @param baudrate Baudrate + /// @return false + /// @return when error was occurred during port opening + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool setBaudRate(const int baudrate); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns current baudrate set into the port handler + /// @description The function returns current baudrate set into the port handler. + /// @return Baudrate + //////////////////////////////////////////////////////////////////////////////// + int getBaudRate(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks how much bytes are able to be read from the port buffer + /// @description The function checks how much bytes are able to be read from the port buffer + /// @description and returns the number. + /// @return Length of read-able bytes in the port buffer + //////////////////////////////////////////////////////////////////////////////// + int getBytesAvailable(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that reads bytes from the port buffer + /// @description The function gets bytes from the port buffer, + /// @description and returns a number of bytes read. + /// @param packet Buffer for the packet received + /// @param length Length of the buffer for read + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes read + //////////////////////////////////////////////////////////////////////////////// + int readPort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that writes bytes on the port buffer + /// @description The function writes bytes on the port buffer, + /// @description and returns a number of bytes which are successfully written. + /// @param packet Buffer which would be written on the port buffer + /// @param length Length of the buffer for write + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes written + //////////////////////////////////////////////////////////////////////////////// + int writePort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with packet_length. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(uint16_t packet_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with msec. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(double msec); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks whether packet timeout is occurred + /// @description The function checks whether current time is passed by the time of packet timeout from the time set by PortHandlerLinux::setPacketTimeout(). + //////////////////////////////////////////////////////////////////////////////// + bool isPacketTimeout(); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_LINUX_PORTHANDLERLINUX_H_ */ diff --git a/include/dynamixel_sdk/port_handler_mac.h b/include/dynamixel_sdk/port_handler_mac.h new file mode 100644 index 0000000..9739084 --- /dev/null +++ b/include/dynamixel_sdk/port_handler_mac.h @@ -0,0 +1,172 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for port control in Mac OS +/// @author Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_MAC_PORTHANDLERMAC_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_MAC_PORTHANDLERMAC_H_ + + +#include "port_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for control port in Mac OS +//////////////////////////////////////////////////////////////////////////////// +class PortHandlerMac : public PortHandler +{ + private: + int socket_fd_; + int baudrate_; + char port_name_[100]; + + double packet_start_time_; + double packet_timeout_; + double tx_time_per_byte; + + bool setupPort(const int cflag_baud); + bool setCustomBaudrate(int speed); + int getCFlagBaud(const int baudrate); + + double getCurrentTime(); + double getTimeSinceStart(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that initializes instance of PortHandler and gets port_name + /// @description The function initializes instance of PortHandler and gets port_name. + //////////////////////////////////////////////////////////////////////////////// + PortHandlerMac(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function calls PortHandlerMac::closePort() to close the port. + //////////////////////////////////////////////////////////////////////////////// + virtual ~PortHandlerMac() { closePort(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that opens the port + /// @description The function calls PortHandlerMac::setBaudRate() to open the port. + /// @return communication results which come from PortHandlerMac::setBaudRate() + //////////////////////////////////////////////////////////////////////////////// + bool openPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function closes the port. + //////////////////////////////////////////////////////////////////////////////// + void closePort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the port + /// @description The function clears the port. + //////////////////////////////////////////////////////////////////////////////// + void clearPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets port name into the port handler + /// @description The function sets port name into the port handler. + /// @param port_name Port name + //////////////////////////////////////////////////////////////////////////////// + void setPortName(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns port name set into the port handler + /// @description The function returns current port name set into the port handler. + /// @return Port name + //////////////////////////////////////////////////////////////////////////////// + char *getPortName(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets baudrate into the port handler + /// @description The function sets baudrate into the port handler. + /// @param baudrate Baudrate + /// @return false + /// @return when error was occurred during port opening + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool setBaudRate(const int baudrate); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns current baudrate set into the port handler + /// @description The function returns current baudrate set into the port handler. + /// @warning Mac OS doesn't support over 230400 bps + /// @return Baudrate + //////////////////////////////////////////////////////////////////////////////// + int getBaudRate(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks how much bytes are able to be read from the port buffer + /// @description The function checks how much bytes are able to be read from the port buffer + /// @description and returns the number. + /// @return Length of read-able bytes in the port buffer + //////////////////////////////////////////////////////////////////////////////// + int getBytesAvailable(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that reads bytes from the port buffer + /// @description The function gets bytes from the port buffer, + /// @description and returns a number of bytes read. + /// @param packet Buffer for the packet received + /// @param length Length of the buffer for read + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes read + //////////////////////////////////////////////////////////////////////////////// + int readPort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that writes bytes on the port buffer + /// @description The function writes bytes on the port buffer, + /// @description and returns a number of bytes which are successfully written. + /// @param packet Buffer which would be written on the port buffer + /// @param length Length of the buffer for write + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes written + //////////////////////////////////////////////////////////////////////////////// + int writePort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with packet_length. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(uint16_t packet_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with msec. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(double msec); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks whether packet timeout is occurred + /// @description The function checks whether current time is passed by the time of packet timeout from the time set by PortHandlerMac::setPacketTimeout(). + //////////////////////////////////////////////////////////////////////////////// + bool isPacketTimeout(); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_MAC_PORTHANDLERMAC_H_ */ diff --git a/include/dynamixel_sdk/port_handler_windows.h b/include/dynamixel_sdk/port_handler_windows.h new file mode 100644 index 0000000..0743b2e --- /dev/null +++ b/include/dynamixel_sdk/port_handler_windows.h @@ -0,0 +1,172 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for port control in Windows +/// @author Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_WINDOWS_PORTHANDLERWINDOWS_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_WINDOWS_PORTHANDLERWINDOWS_H_ + +#include + +#include "port_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for control port in Windows +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC PortHandlerWindows : public PortHandler +{ + private: + HANDLE serial_handle_; + LARGE_INTEGER freq_, counter_; + + int baudrate_; + char port_name_[100]; + + double packet_start_time_; + double packet_timeout_; + double tx_time_per_byte_; + + bool setupPort(const int baudrate); + + double getCurrentTime(); + double getTimeSinceStart(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that initializes instance of PortHandler and gets port_name + /// @description The function initializes instance of PortHandler and gets port_name. + //////////////////////////////////////////////////////////////////////////////// + PortHandlerWindows(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function calls PortHandlerWindows::closePort() to close the port. + //////////////////////////////////////////////////////////////////////////////// + virtual ~PortHandlerWindows() { closePort(); } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that opens the port + /// @description The function calls PortHandlerWindows::setBaudRate() to open the port. + /// @return communication results which come from PortHandlerWindows::setBaudRate() + //////////////////////////////////////////////////////////////////////////////// + bool openPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that closes the port + /// @description The function closes the port. + //////////////////////////////////////////////////////////////////////////////// + void closePort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that clears the port + /// @description The function clears the port. + //////////////////////////////////////////////////////////////////////////////// + void clearPort(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets port name into the port handler + /// @description The function sets port name into the port handler. + /// @param port_name Port name + //////////////////////////////////////////////////////////////////////////////// + void setPortName(const char *port_name); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns port name set into the port handler + /// @description The function returns current port name set into the port handler. + /// @return Port name + //////////////////////////////////////////////////////////////////////////////// + char *getPortName(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets baudrate into the port handler + /// @description The function sets baudrate into the port handler. + /// @param baudrate Baudrate + /// @return false + /// @return when error was occurred during port opening + /// @return or true + //////////////////////////////////////////////////////////////////////////////// + bool setBaudRate(const int baudrate); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns current baudrate set into the port handler + /// @description The function returns current baudrate set into the port handler. + /// @return Baudrate + //////////////////////////////////////////////////////////////////////////////// + int getBaudRate(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks how much bytes are able to be read from the port buffer + /// @description The function checks how much bytes are able to be read from the port buffer + /// @description and returns the number. + /// @return Length of read-able bytes in the port buffer + //////////////////////////////////////////////////////////////////////////////// + int getBytesAvailable(); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that reads bytes from the port buffer + /// @description The function gets bytes from the port buffer, + /// @description and returns a number of bytes read. + /// @param packet Buffer for the packet received + /// @param length Length of the buffer for read + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes read + //////////////////////////////////////////////////////////////////////////////// + int readPort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that writes bytes on the port buffer + /// @description The function writes bytes on the port buffer, + /// @description and returns a number of bytes which are successfully written. + /// @param packet Buffer which would be written on the port buffer + /// @param length Length of the buffer for write + /// @return -1 + /// @return when error was occurred + /// @return or Length of bytes written + //////////////////////////////////////////////////////////////////////////////// + int writePort(uint8_t *packet, int length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with packet_length. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(uint16_t packet_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that sets and starts stopwatch for watching packet timeout + /// @description The function sets the stopwatch by getting current time and the time of packet timeout with msec. + /// @param packet_length Length of the packet expected to be received + //////////////////////////////////////////////////////////////////////////////// + void setPacketTimeout(double msec); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that checks whether packet timeout is occurred + /// @description The function checks whether current time is passed by the time of packet timeout from the time set by PortHandlerWindows::setPacketTimeout(). + //////////////////////////////////////////////////////////////////////////////// + bool isPacketTimeout(); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_WINDOWS_PORTHANDLERWINDOWS_H_ */ diff --git a/include/dynamixel_sdk/protocol1_packet_handler.h b/include/dynamixel_sdk/protocol1_packet_handler.h new file mode 100644 index 0000000..54c054d --- /dev/null +++ b/include/dynamixel_sdk/protocol1_packet_handler.h @@ -0,0 +1,537 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for Protocol 1.0 Dynamixel packet control +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PROTOCOL1PACKETHANDLER_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PROTOCOL1PACKETHANDLER_H_ + + +#include "packet_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for control Dynamixel by using Protocol1.0 +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC Protocol1PacketHandler : public PacketHandler +{ + private: + static Protocol1PacketHandler *unique_instance_; + + Protocol1PacketHandler(); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns Protocol1PacketHandler instance + /// @return Protocol1PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + static Protocol1PacketHandler *getInstance() { return unique_instance_; } + + virtual ~Protocol1PacketHandler() { } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns Protocol version used in Protocol1PacketHandler (1.0) + /// @return 1.0 + //////////////////////////////////////////////////////////////////////////////// + float getProtocolVersion() { return 1.0; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets description of communication result + /// @param result Communication result which might be gotten by the tx rx functions + /// @return description of communication result in const char* (string) + //////////////////////////////////////////////////////////////////////////////// + const char *getTxRxResult (int result); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets description of hardware error + /// @param error Dynamixel hardware error which might be gotten by the tx rx functions + /// @return description of hardware error in const char* (string) + //////////////////////////////////////////////////////////////////////////////// + const char *getRxPacketError (uint8_t error); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits the instruction packet txpacket via PortHandler port. + /// @description The function clears the port buffer by PortHandler::clearPort() function, + /// @description then transmits txpacket by PortHandler::writePort() function. + /// @description The function activates only when the port is not busy and when the packet is already written on the port buffer + /// @param port PortHandler instance + /// @param txpacket packet for transmission + /// @return COMM_PORT_BUSY + /// @return when the port is already in use + /// @return COMM_TX_ERROR + /// @return when txpacket is out of range described by TXPACKET_MAX_LEN + /// @return COMM_TX_FAIL + /// @return when written packet is shorter than expected + /// @return or COMM_SUCCESS + //////////////////////////////////////////////////////////////////////////////// + int txPacket (PortHandler *port, uint8_t *txpacket); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives packet (rxpacket) during designated time via PortHandler port + /// @description The function repeatedly tries to receive rxpacket by PortHandler::readPort() function. + /// @description It breaks out + /// @description when PortHandler::isPacketTimeout() shows the timeout, + /// @description when rxpacket seemed as corrupted, or + /// @description when nothing received + /// @param port PortHandler instance + /// @param rxpacket received packet + /// @return COMM_RX_CORRUPT + /// @return when it received the packet but it couldn't find header in the packet + /// @return when it found header in the packet but the id, length or error value is out of range + /// @return when it received the packet but it is shorted than expected + /// @return COMM_RX_TIMEOUT + /// @return when there is no rxpacket received until PortHandler::isPacketTimeout() shows the timeout + /// @return COMM_SUCCESS + /// @return when rxpacket passes checksum test + /// @return or COMM_RX_FAIL + //////////////////////////////////////////////////////////////////////////////// + int rxPacket (PortHandler *port, uint8_t *rxpacket); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits packet (txpacket) and receives packet (rxpacket) during designated time via PortHandler port + /// @description The function calls Protocol1PacketHandler::txPacket(), + /// @description and calls Protocol1PacketHandler::rxPacket() if it succeeds Protocol1PacketHandler::txPacket(). + /// @description It breaks out + /// @description when it fails Protocol1PacketHandler::txPacket(), + /// @description when txpacket is called by Protocol1PacketHandler::broadcastPing() / Protocol1PacketHandler::syncWriteTxOnly() / Protocol1PacketHandler::regWriteTxOnly / Protocol1PacketHandler::action + /// @param port PortHandler instance + /// @param txpacket packet for transmission + /// @param rxpacket received packet + /// @return COMM_SUCCESS + /// @return when it succeeds Protocol1PacketHandler::txPacket() and Protocol1PacketHandler::rxPacket() + /// @return or the other communication results which come from Protocol1PacketHandler::txPacket() and Protocol1PacketHandler::rxPacket() + //////////////////////////////////////////////////////////////////////////////// + int txRxPacket (PortHandler *port, uint8_t *txpacket, uint8_t *rxpacket, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that pings Dynamixel but doesn't take its model number + /// @description The function calls Protocol1PacketHandler::ping() which gets Dynamixel model number, + /// @description but doesn't carry the model number + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::ping() + //////////////////////////////////////////////////////////////////////////////// + int ping (PortHandler *port, uint8_t id, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that pings Dynamixel and takes its model number + /// @description The function makes an instruction packet with INST_PING, + /// @description transmits the packet with Protocol1PacketHandler::txRxPacket(), + /// @description and call Protocol1PacketHandler::readTxRx to read model_number in the rx buffer. + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return COMM_SUCCESS + /// @return when it succeeds to ping Dynamixel and get model_number from it + /// @return or the other communication results which come from Protocol1PacketHandler::txRxPacket() and Protocol1PacketHandler::readTxRx() + //////////////////////////////////////////////////////////////////////////////// + int ping (PortHandler *port, uint8_t id, uint16_t *model_number, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only in Protocol 2.0) The function that pings all connected Dynamixel + /// @param port PortHandler instance + /// @param id_list ID list of Dynamixels which are found by broadcast ping + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + int broadcastPing (PortHandler *port, std::vector &id_list); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixels run as written in the Dynamixel register + /// @description The function makes an instruction packet with INST_ACTION, + /// @description transmits the packet with Protocol1PacketHandler::txRxPacket(). + /// @description To use this function, Dynamixel register should be set by Protocol1PacketHandler::regWriteTxOnly() or Protocol1PacketHandler::regWriteTxRx() + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int action (PortHandler *port, uint8_t id); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only in Protocol 2.0) The function that makes Dynamixel reboot + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + int reboot (PortHandler *port, uint8_t id, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only in Protocol 2.0) The function that reset multi-turn revolution information of Dynamixel + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + int clearMultiTurn (PortHandler *port, uint8_t id, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixel reset as it was produced in the factory + /// @description The function makes an instruction packet with INST_FACTORY_RESET, + /// @description transmits the packet with Protocol1PacketHandler::txRxPacket(). + /// @description Be careful of the use. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param option (Not available in Protocol 1.0) Reset option + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int factoryReset (PortHandler *port, uint8_t id, uint8_t option, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_READ instruction packet + /// @description The function makes an instruction packet with INST_READ, + /// @description transmits the packet with Protocol1PacketHandler::txPacket(). + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return or the other communication results which come from Protocol1PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int readTx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives the packet and reads the data in the packet + /// @description The function receives the packet which might be come by previous INST_READ instruction packet transmission, + /// @description gets the data from the packet. + /// @param port PortHandler instance + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::rxPacket() + //////////////////////////////////////////////////////////////////////////////// + int readRx (PortHandler *port, uint8_t id, uint16_t length, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_READ instruction packet, and read data from received packet + /// @description The function makes an instruction packet with INST_READ, + /// @description transmits and receives the packet with Protocol1PacketHandler::txRxPacket(), + /// @description gets the data from the packet. + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return or the other communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int readTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readTx() function for reading 1 byte data + /// @description The function calls Protocol1PacketHandler::readTx() function for reading 1 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from Protocol1PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + int read1ByteTx (PortHandler *port, uint8_t id, uint16_t address); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readRx() function and reads 1 byte data on the packet + /// @description The function calls Protocol1PacketHandler::readRx() function, + /// @description gets 1 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + int read1ByteRx (PortHandler *port, uint8_t id, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readTxRx() function for reading 1 byte data + /// @description The function calls Protocol1PacketHandler::readTxRx(), + /// @description gets 1 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int read1ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readTx() function for reading 2 byte data + /// @description The function calls Protocol1PacketHandler::readTx() function for reading 2 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from Protocol1PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + int read2ByteTx (PortHandler *port, uint8_t id, uint16_t address); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readRx() function and reads 2 byte data on the packet + /// @description The function calls Protocol1PacketHandler::readRx() function, + /// @description gets 2 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + int read2ByteRx (PortHandler *port, uint8_t id, uint16_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readTxRx() function for reading 2 byte data + /// @description The function calls Protocol1PacketHandler::readTxRx(), + /// @description gets 2 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int read2ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readTx() function for reading 4 byte data + /// @description The function calls Protocol1PacketHandler::readTx() function for reading 4 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from Protocol1PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + int read4ByteTx (PortHandler *port, uint8_t id, uint16_t address); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readRx() function and reads 4 byte data on the packet + /// @description The function calls Protocol1PacketHandler::readRx() function, + /// @description gets 4 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + int read4ByteRx (PortHandler *port, uint8_t id, uint32_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::readTxRx() function for reading 4 byte data + /// @description The function calls Protocol1PacketHandler::readTxRx(), + /// @description gets 4 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int read4ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint32_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_WRITE instruction packet with the data for write + /// @description The function makes an instruction packet with INST_WRITE and the data for write, + /// @description transmits the packet with Protocol1PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol1PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int writeTxOnly (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_WRITE instruction packet with the data for write, and receives the packet + /// @description The function makes an instruction packet with INST_WRITE and the data for write, + /// @description transmits and receives the packet with Protocol1PacketHandler::txRxPacket(), + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int writeTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::writeTxOnly() for writing 1 byte data + /// @description The function calls Protocol1PacketHandler::writeTxOnly() for writing 1 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol1PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + int write1ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint8_t data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::writeTxRx() for writing 1 byte data and receives the packet + /// @description The function calls Protocol1PacketHandler::writeTxRx() for writing 1 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + int write1ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint8_t data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::writeTxOnly() for writing 2 byte data + /// @description The function calls Protocol1PacketHandler::writeTxOnly() for writing 2 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol1PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + int write2ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint16_t data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::writeTxRx() for writing 2 byte data and receives the packet + /// @description The function calls Protocol1PacketHandler::writeTxRx() for writing 2 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + int write2ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::writeTxOnly() for writing 4 byte data + /// @description The function calls Protocol1PacketHandler::writeTxOnly() for writing 4 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol1PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + int write4ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint32_t data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol1PacketHandler::writeTxRx() for writing 4 byte data and receives the packet + /// @description The function calls Protocol1PacketHandler::writeTxRx() for writing 4 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + int write4ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint32_t data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_REG_WRITE instruction packet with the data for writing on the Dynamixel register + /// @description The function makes an instruction packet with INST_REG_WRITE and the data for writing on the Dynamixel register, + /// @description transmits the packet with Protocol1PacketHandler::txPacket(). + /// @description The data written in the register will act when INST_ACTION instruction packet is transmitted to the Dynamxel. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol1PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int regWriteTxOnly (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_REG_WRITE instruction packet with the data for writing on the Dynamixel register, and receives the packet + /// @description The function makes an instruction packet with INST_REG_WRITE and the data for writing on the Dynamixel register, + /// @description transmits and receives the packet with Protocol1PacketHandler::txRxPacket(), + /// @description gets the error from the packet. + /// @description The data written in the register will act when INST_ACTION instruction packet is transmitted to the Dynamxel. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int regWriteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only in Protocol 2.0) The function that transmits Sync Read instruction packet + /// @param port PortHandler instance + /// @param start_address Address of the data for Sync Read + /// @param data_length Length of the data for Sync Read + /// @param param Parameter for Sync Read + /// @param param_length Length of the data for Sync Read + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + int syncReadTx (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length); + // SyncReadRx -> GroupSyncRead class + // SyncReadTxRx -> GroupSyncRead class + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits Sync Write instruction packet + /// @description The function makes an instruction packet with INST_SYNC_WRITE, + /// @description transmits the packet with Protocol1PacketHandler::txRxPacket(). + /// @param port PortHandler instance + /// @param start_address Address of the data for Sync Write + /// @param data_length Length of the data for Sync Write + /// @param param Parameter for Sync Write {ID1, DATA0, DATA1, ..., DATAn, ID2, DATA0, DATA1, ..., DATAn, ID3, DATA0, DATA1, ..., DATAn} + /// @param param_length Length of the data for Sync Write + /// @return communication results which come from Protocol1PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int syncWriteTxOnly (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only on Dynamixel MX / X series) The function that transmits Bulk Read instruction packet + /// @description The function makes an instruction packet with INST_BULK_READ, + /// @description transmits the packet with Protocol1PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param param Parameter for Bulk Read {LEN1, ID1, ADDR1, LEN2, ID2, ADDR2, ...} + /// @param param_length Length of the data for Bulk Read + /// @return communication results which come from Protocol1PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int bulkReadTx (PortHandler *port, uint8_t *param, uint16_t param_length); + // BulkReadRx -> GroupBulkRead class + // BulkReadTxRx -> GroupBulkRead class + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only in Protocol 2.0) The function that transmits Bulk Write instruction packet + /// @param port PortHandler instance + /// @param param Parameter for Bulk Write + /// @param param_length Length of the data for Bulk Write + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + int bulkWriteTxOnly (PortHandler *port, uint8_t *param, uint16_t param_length); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PROTOCOL1PACKETHANDLER_H_ */ diff --git a/include/dynamixel_sdk/protocol2_packet_handler.h b/include/dynamixel_sdk/protocol2_packet_handler.h new file mode 100644 index 0000000..d6a2230 --- /dev/null +++ b/include/dynamixel_sdk/protocol2_packet_handler.h @@ -0,0 +1,554 @@ +/******************************************************************************* +* Copyright 2017 ROBOTIS CO., LTD. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////// +/// @file The file for Protocol 2.0 Dynamixel packet control +/// @author Zerom, Leon (RyuWoon Jung) +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PROTOCOL2PACKETHANDLER_H_ +#define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PROTOCOL2PACKETHANDLER_H_ + + +#include "packet_handler.h" + +namespace dynamixel +{ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief The class for control Dynamixel by using Protocol2.0 +//////////////////////////////////////////////////////////////////////////////// +class WINDECLSPEC Protocol2PacketHandler : public PacketHandler +{ + private: + static Protocol2PacketHandler *unique_instance_; + + Protocol2PacketHandler(); + + uint16_t updateCRC(uint16_t crc_accum, uint8_t *data_blk_ptr, uint16_t data_blk_size); + void addStuffing(uint8_t *packet); + void removeStuffing(uint8_t *packet); + + public: + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns Protocol2PacketHandler instance + /// @return Protocol2PacketHandler instance + //////////////////////////////////////////////////////////////////////////////// + static Protocol2PacketHandler *getInstance() { return unique_instance_; } + + virtual ~Protocol2PacketHandler() { } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that returns Protocol version used in Protocol2PacketHandler (2.0) + /// @return 2.0 + //////////////////////////////////////////////////////////////////////////////// + float getProtocolVersion() { return 2.0; } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets description of communication result + /// @param result Communication result which might be gotten by the tx rx functions + /// @return description of communication result in const char* (string) + //////////////////////////////////////////////////////////////////////////////// + const char *getTxRxResult (int result); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that gets description of hardware error + /// @param error Dynamixel hardware error which might be gotten by the tx rx functions + /// @return description of hardware error in const char* (string) + //////////////////////////////////////////////////////////////////////////////// + const char *getRxPacketError (uint8_t error); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits the instruction packet txpacket via PortHandler port. + /// @description The function clears the port buffer by PortHandler::clearPort() function, + /// @description then transmits txpacket by PortHandler::writePort() function. + /// @description The function activates only when the port is not busy and when the packet is already written on the port buffer + /// @param port PortHandler instance + /// @param txpacket packet for transmission + /// @return COMM_PORT_BUSY + /// @return when the port is already in use + /// @return COMM_TX_ERROR + /// @return when txpacket is out of range described by TXPACKET_MAX_LEN + /// @return COMM_TX_FAIL + /// @return when written packet is shorter than expected + /// @return or COMM_SUCCESS + //////////////////////////////////////////////////////////////////////////////// + int txPacket (PortHandler *port, uint8_t *txpacket); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives packet (rxpacket) during designated time via PortHandler port + /// @description The function repeatedly tries to receive rxpacket by PortHandler::readPort() function. + /// @description It breaks out + /// @description when PortHandler::isPacketTimeout() shows the timeout, + /// @description when rxpacket seemed as corrupted, or + /// @description when nothing received + /// @param port PortHandler instance + /// @param rxpacket received packet + /// @return COMM_RX_CORRUPT + /// @return when it received the packet but it couldn't find header in the packet + /// @return when it found header in the packet but the id, length or error value is out of range + /// @return when it received the packet but it is shorted than expected + /// @return COMM_RX_TIMEOUT + /// @return when there is no rxpacket received until PortHandler::isPacketTimeout() shows the timeout + /// @return COMM_SUCCESS + /// @return when rxpacket passes checksum test + /// @return or COMM_RX_FAIL + //////////////////////////////////////////////////////////////////////////////// + int rxPacket (PortHandler *port, uint8_t *rxpacket); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits packet (txpacket) and receives packet (rxpacket) during designated time via PortHandler port + /// @description The function calls Protocol2PacketHandler::txPacket(), + /// @description and calls Protocol2PacketHandler::rxPacket() if it succeeds Protocol2PacketHandler::txPacket(). + /// @description It breaks out + /// @description when it fails Protocol2PacketHandler::txPacket(), + /// @description when txpacket is called by Protocol2PacketHandler::broadcastPing() / Protocol2PacketHandler::syncWriteTxOnly() / Protocol2PacketHandler::regWriteTxOnly / Protocol2PacketHandler::action + /// @param port PortHandler instance + /// @param txpacket packet for transmission + /// @param rxpacket received packet + /// @return COMM_SUCCESS + /// @return when it succeeds Protocol2PacketHandler::txPacket() and Protocol2PacketHandler::rxPacket() + /// @return or the other communication results which come from Protocol2PacketHandler::txPacket() and Protocol2PacketHandler::rxPacket() + //////////////////////////////////////////////////////////////////////////////// + int txRxPacket (PortHandler *port, uint8_t *txpacket, uint8_t *rxpacket, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that pings Dynamixel but doesn't take its model number + /// @description The function calls Protocol2PacketHandler::ping() which gets Dynamixel model number, + /// @description but doesn't carry the model number + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::ping() + //////////////////////////////////////////////////////////////////////////////// + int ping (PortHandler *port, uint8_t id, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that pings Dynamixel and takes its model number + /// @description The function makes an instruction packet with INST_PING, + /// @description transmits the packet with Protocol2PacketHandler::txRxPacket(), + /// @description and call Protocol2PacketHandler::readTxRx to read model_number in the rx buffer. + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return COMM_SUCCESS + /// @return when it succeeds to ping Dynamixel and get model_number from it + /// @return or the other communication results which come from Protocol2PacketHandler::txRxPacket() and Protocol2PacketHandler::readTxRx() + //////////////////////////////////////////////////////////////////////////////// + int ping (PortHandler *port, uint8_t id, uint16_t *model_number, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief (Available only in Protocol 2.0) The function that pings all connected Dynamixel + /// @param port PortHandler instance + /// @param id_list ID list of Dynamixels which are found by broadcast ping + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + int broadcastPing (PortHandler *port, std::vector &id_list); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixels run as written in the Dynamixel register + /// @description The function makes an instruction packet with INST_ACTION, + /// @description transmits the packet with Protocol2PacketHandler::txRxPacket(). + /// @description To use this function, Dynamixel register should be set by Protocol2PacketHandler::regWriteTxOnly() or Protocol2PacketHandler::regWriteTxRx() + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int action (PortHandler *port, uint8_t id); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixel reboot + /// @description The function makes an instruction packet with INST_REBOOT, + /// @description transmits the packet with Protocol2PacketHandler::txRxPacket(), + /// @description then Dynamixel reboots. + /// @description During reboot, its LED will blink. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + //////////////////////////////////////////////////////////////////////////////// + int reboot (PortHandler *port, uint8_t id, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that reset multi-turn revolution information of Dynamixel + /// @description The function makes an instruction packet with INST_CLEAR, + /// @description transmits the packet with Protocol2PacketHandler::txRxPacket(). + /// @description Applied Products : MX with Protocol 2.0 (Firmware v42 or above), + /// @description Dynamixel X-series (Firmware v42 or above). + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int clearMultiTurn (PortHandler *port, uint8_t id, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that makes Dynamixel reset as it was produced in the factory + /// @description The function makes an instruction packet with INST_FACTORY_RESET, + /// @description transmits the packet with Protocol2PacketHandler::txRxPacket(). + /// @description Be careful of the use. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param option Reset option (0xFF for reset all values / 0x01 for reset all values except ID / 0x02 for reset all values except ID and Baudrate) + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int factoryReset (PortHandler *port, uint8_t id, uint8_t option, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_READ instruction packet + /// @description The function makes an instruction packet with INST_READ, + /// @description transmits the packet with Protocol2PacketHandler::txPacket(). + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return or the other communication results which come from Protocol2PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int readTx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that receives the packet and reads the data in the packet + /// @description The function receives the packet which might be come by previous INST_READ instruction packet transmission, + /// @description gets the data from the packet. + /// @param port PortHandler instance + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::rxPacket() + //////////////////////////////////////////////////////////////////////////////// + int readRx (PortHandler *port, uint8_t id, uint16_t length, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_READ instruction packet, and read data from received packet + /// @description The function makes an instruction packet with INST_READ, + /// @description transmits and receives the packet with Protocol2PacketHandler::txRxPacket(), + /// @description gets the data from the packet. + /// @description It breaks out + /// @description when it tries to transmit to BROADCAST_ID + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return COMM_NOT_AVAILABLE + /// @return when it tries to transmit to BROADCAST_ID + /// @return or the other communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int readTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readTx() function for reading 1 byte data + /// @description The function calls Protocol2PacketHandler::readTx() function for reading 1 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from Protocol2PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + int read1ByteTx (PortHandler *port, uint8_t id, uint16_t address); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readRx() function and reads 1 byte data on the packet + /// @description The function calls Protocol2PacketHandler::readRx() function, + /// @description gets 1 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + int read1ByteRx (PortHandler *port, uint8_t id, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readTxRx() function for reading 1 byte data + /// @description The function calls Protocol2PacketHandler::readTxRx(), + /// @description gets 1 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int read1ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readTx() function for reading 2 byte data + /// @description The function calls Protocol2PacketHandler::readTx() function for reading 2 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from Protocol2PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + int read2ByteTx (PortHandler *port, uint8_t id, uint16_t address); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readRx() function and reads 2 byte data on the packet + /// @description The function calls Protocol2PacketHandler::readRx() function, + /// @description gets 2 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + int read2ByteRx (PortHandler *port, uint8_t id, uint16_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readTxRx() function for reading 2 byte data + /// @description The function calls Protocol2PacketHandler::readTxRx(), + /// @description gets 2 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int read2ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readTx() function for reading 4 byte data + /// @description The function calls Protocol2PacketHandler::readTx() function for reading 4 byte data + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @return communication results which come from Protocol2PacketHandler::readTx() + //////////////////////////////////////////////////////////////////////////////// + int read4ByteTx (PortHandler *port, uint8_t id, uint16_t address); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readRx() function and reads 4 byte data on the packet + /// @description The function calls Protocol2PacketHandler::readRx() function, + /// @description gets 4 byte data from the packet. + /// @param port PortHandler instance + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::readRx() + //////////////////////////////////////////////////////////////////////////////// + int read4ByteRx (PortHandler *port, uint8_t id, uint32_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::readTxRx() function for reading 4 byte data + /// @description The function calls Protocol2PacketHandler::readTxRx(), + /// @description gets 4 byte data from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for read + /// @param length Length of the data for read + /// @param data Data extracted from the packet + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int read4ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint32_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_WRITE instruction packet with the data for write + /// @description The function makes an instruction packet with INST_WRITE and the data for write, + /// @description transmits the packet with Protocol2PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol2PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int writeTxOnly (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_WRITE instruction packet with the data for write, and receives the packet + /// @description The function makes an instruction packet with INST_WRITE and the data for write, + /// @description transmits and receives the packet with Protocol2PacketHandler::txRxPacket(), + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int writeTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::writeTxOnly() for writing 1 byte data + /// @description The function calls Protocol2PacketHandler::writeTxOnly() for writing 1 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol2PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + int write1ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint8_t data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::writeTxRx() for writing 1 byte data and receives the packet + /// @description The function calls Protocol2PacketHandler::writeTxRx() for writing 1 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + int write1ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint8_t data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::writeTxOnly() for writing 2 byte data + /// @description The function calls Protocol2PacketHandler::writeTxOnly() for writing 2 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol2PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + int write2ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint16_t data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::writeTxRx() for writing 2 byte data and receives the packet + /// @description The function calls Protocol2PacketHandler::writeTxRx() for writing 2 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + int write2ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::writeTxOnly() for writing 4 byte data + /// @description The function calls Protocol2PacketHandler::writeTxOnly() for writing 4 byte data. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol2PacketHandler::writeTxOnly() + //////////////////////////////////////////////////////////////////////////////// + int write4ByteTxOnly(PortHandler *port, uint8_t id, uint16_t address, uint32_t data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that calls Protocol2PacketHandler::writeTxRx() for writing 4 byte data and receives the packet + /// @description The function calls Protocol2PacketHandler::writeTxRx() for writing 4 byte data and receves the packet, + /// @description gets the error from the packet. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::writeTxRx() + //////////////////////////////////////////////////////////////////////////////// + int write4ByteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint32_t data, uint8_t *error = 0); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_REG_WRITE instruction packet with the data for writing on the Dynamixel register + /// @description The function makes an instruction packet with INST_REG_WRITE and the data for writing on the Dynamixel register, + /// @description transmits the packet with Protocol2PacketHandler::txPacket(). + /// @description The data written in the register will act when INST_ACTION instruction packet is transmitted to the Dynamxel. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @return communication results which come from Protocol2PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int regWriteTxOnly (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_REG_WRITE instruction packet with the data for writing on the Dynamixel register, and receives the packet + /// @description The function makes an instruction packet with INST_REG_WRITE and the data for writing on the Dynamixel register, + /// @description transmits and receives the packet with Protocol2PacketHandler::txRxPacket(), + /// @description gets the error from the packet. + /// @description The data written in the register will act when INST_ACTION instruction packet is transmitted to the Dynamxel. + /// @param port PortHandler instance + /// @param id Dynamixel ID + /// @param address Address of the data for write + /// @param length Length of the data for write + /// @param data Data for write + /// @param error Dynamixel hardware error + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int regWriteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error = 0); + + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_SYNC_READ instruction packet + /// @description The function makes an instruction packet with INST_SYNC_READ, + /// @description transmits the packet with Protocol2PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param start_address Address of the data for Sync Read + /// @param data_length Length of the data for Sync Read + /// @param param Parameter for Sync Read + /// @param param_length Length of the data for Sync Read + /// @return communication results which come from Protocol2PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int syncReadTx (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length); + // SyncReadRx -> GroupSyncRead class + // SyncReadTxRx -> GroupSyncRead class + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_SYNC_WRITE instruction packet + /// @description The function makes an instruction packet with INST_SYNC_WRITE, + /// @description transmits the packet with Protocol2PacketHandler::txRxPacket(). + /// @param port PortHandler instance + /// @param start_address Address of the data for Sync Write + /// @param data_length Length of the data for Sync Write + /// @param param Parameter for Sync Write {ID1, DATA0, DATA1, ..., DATAn, ID2, DATA0, DATA1, ..., DATAn, ID3, DATA0, DATA1, ..., DATAn} + /// @param param_length Length of the data for Sync Write + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int syncWriteTxOnly (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_BULK_READ instruction packet + /// @description The function makes an instruction packet with INST_BULK_READ, + /// @description transmits the packet with Protocol2PacketHandler::txPacket(). + /// @param port PortHandler instance + /// @param param Parameter for Bulk Read {ID1, ADDR_L1, ADDR_H1, LEN_L1, LEN_H1, ID2, ADDR_L2, ADDR_H2, LEN_L2, LEN_H2, ...} + /// @param param_length Length of the data for Bulk Read + /// @return communication results which come from Protocol2PacketHandler::txPacket() + //////////////////////////////////////////////////////////////////////////////// + int bulkReadTx (PortHandler *port, uint8_t *param, uint16_t param_length); + // BulkReadRx -> GroupBulkRead class + // BulkReadTxRx -> GroupBulkRead class + + //////////////////////////////////////////////////////////////////////////////// + /// @brief The function that transmits INST_BULK_WRITE instruction packet + /// @description The function makes an instruction packet with INST_BULK_WRITE, + /// @description transmits the packet with Protocol2PacketHandler::txRxPacket(). + /// @param port PortHandler instance + /// @param param Parameter for Bulk Write {ID1, START_ADDR_L, START_ADDR_H, DATA_LEN_L, DATA_LEN_H, DATA0, DATA1, ..., DATAn, ID2, START_ADDR_L, START_ADDR_H, DATA_LEN_L, DATA_LEN_H, DATA0, DATA1, ..., DATAn} + /// @param param_length Length of the data for Bulk Write + /// @return communication results which come from Protocol2PacketHandler::txRxPacket() + //////////////////////////////////////////////////////////////////////////////// + int bulkWriteTxOnly (PortHandler *port, uint8_t *param, uint16_t param_length); +}; + +} + + +#endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PROTOCOL2PACKETHANDLER_H_ */ diff --git a/make_run/Makefile b/make_run/Makefile index 38378bc..109d80b 100644 --- a/make_run/Makefile +++ b/make_run/Makefile @@ -17,7 +17,7 @@ TARGET = exampleServo # Directories path creation: Include and Object -DIR_DXL = ../ +DIR_DXL = .. DIR_OBJS = .objects # Get platform architecture, set the correct Dynamixel library, and compiler option @@ -28,6 +28,13 @@ ifeq ($(ARCH),armv7l) CXFLAGS = -O2 -O3 -DLINUX -D_GNU_SOURCE -Wall $(INCLUDES) -g INCLUDES += -I$(DIR_DXL)/include/dynamixel_sdk_raspberry endif +# Jetson Nano's architecture is aarch64 +ifeq ($(ARCH),aarch64) + LIBRARIES += -ldxl_sbc_cpp + CCFLAGS = -O2 -O3 -DLINUX -D_GNU_SOURCE -Wall $(INCLUDES) -g + CXFLAGS = -O2 -O3 -DLINUX -D_GNU_SOURCE -Wall $(INCLUDES) -g + INCLUDES += -I$(DIR_DXL)/include/dynamixel_sdk +endif ifeq ($(ARCH),x86_64) LIBRARIES += -ldxl_x64_cpp