ROBOTIS-GIT / DynamixelSDK

ROBOTIS Dynamixel SDK (Protocol1.0/2.0)
http://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/overview/
Apache License 2.0
466 stars 412 forks source link

[3.7.51][C++][U2D2][XL430-W250] Issue : read4ByteTxRx in protocol2_packet_handler.cpp return "[TxRxResult] There is no status packet!" #561

Open Factao opened 2 years ago

Factao commented 2 years ago
  1. Which DYNAMIXEL SDK version do you use? 3.7.31

  2. Which programming language/tool do you use? C++ (with Qt)

  3. Which operating system do you use? Windows 10

  4. Which USB serial converter do you use? U2D2

  5. Which DYNAMIXEL do you use? XL430-W250

  6. Have you searched the issue from the closed issue threads? Yes, but none seem to provide an adequate solution

  7. Please describe the issue in detail I cannot read the present position of my XL430-W250, despite being able to write in goal position. This is also true for every other information in memory. More precisely, read4ByteTxRx is returning "[TxRxResult] There is no status packet!" and the value returned does not make sense (something along the line of -1264054379).

  8. How can we reproduce the issue? You may either reproduce the error using my code or the modified sample code below.

1-Download Qt 5.12.2 (not the latest version, otherwise, you'll need to modify my code) 2-Change the serials port in app.cpp (in the constructor) for both the XL430 and the Arduino (you can also just use another XL430 instead of the arduino since the second serial port have no functionality yet) 3-Change the directory to the library in the .pro 4-make sure you compile with the MSCV 2019 compiler 5-Run qmake and build 6-run the little program I made

It is important to specify that only the class com is related to dynamixel. If anything is not functional, I'll provide a more shaved down version of this code. Please, take note this code is still in it's early day and partially in french.

Alternatively, if you do not think you need all of this, there is a slightly modified version of the read write sample code in main.cpp. The only difference is that function like printRxPacketError are replaced by "std::cout<getRxPacketError(dxl_error)<<std::endl;", allowing the program to work. For some unknown reason, this sample code does not succeed in changing the goal position of the servo motor, but it does read and return the same error as my own code.

Here is the sample code: `#ifdef linux

include

include

include

elif defined(_WIN32) || defined(_WIN64)

include

endif

include

include

include "dynamixel_sdk.h" // Uses DYNAMIXEL SDK library

// Control table address

define ADDR_PRO_TORQUE_ENABLE 64 // Control table address is different in Dynamixel model

define ADDR_PRO_GOAL_POSITION 116

define ADDR_PRO_PRESENT_POSITION 132

define XL_430_ID_ADD 7

define XL_430_MAX_POS_ADD 48

define XL_430_MIN_POS_ADD 52

define XL_430_TORQUE_EN_ADD 64

define XL_430_PRO_ACC_ADD 108 //214.577rev/min^2

define XL_430_PRO_VEL_ADD 112 //0.229rev/min

define XL_430_GOAL_POS_ADD 116

define XL_430_PRE_LOAD_ADD 126

define XL_430_PRE_VEL_ADD 128

define XL_430_PRE_POS_ADD 132

// Protocol version

define PROTOCOL_VERSION 2.0 // See which protocol version is used in the Dynamixel

// Default setting

define DXL_ID 1 // Dynamixel ID: 1

define BAUDRATE 57600

define DEVICENAME "COM3" // Check which port is being used on your controller

                                                        // ex) Windows: "COM1"   Linux: "/dev/ttyUSB0"

define TORQUE_ENABLE 1 // Value for enabling the torque

define TORQUE_DISABLE 0 // Value for disabling the torque

define DXL_MINIMUM_POSITION_VALUE 0 // Dynamixel will rotate between this value

define DXL_MAXIMUM_POSITION_VALUE 4000 // and this value (note that the Dynamixel would not move when the position value is out of movable range. Check e-manual about the range of the Dynamixel you use.)

define DXL_MOVING_STATUS_THRESHOLD 20 // Dynamixel moving status threshold

define ESC_ASCII_VALUE 0x1b

int getch() {

ifdef linux

struct termios oldt, newt; int ch; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); return ch;

elif defined(_WIN32) || defined(_WIN64)

return _getch();

endif

}

int kbhit(void) {

ifdef linux

struct termios oldt, newt; int ch; int oldf;

tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

ch = getchar();

tcsetattr(STDIN_FILENO, TCSANOW, &oldt); fcntl(STDIN_FILENO, F_SETFL, oldf);

if (ch != EOF) { ungetc(ch, stdin); return 1; }

return 0;

elif defined(_WIN32) || defined(_WIN64)

return _kbhit();

endif

}

int main() { // Initialize PortHandler instance // Set the port path // Get methods and members of PortHandlerLinux or PortHandlerWindows dynamixel::PortHandler *portHandler = dynamixel::PortHandler::getPortHandler(DEVICENAME);

// Initialize PacketHandler instance // Set the protocol version // Get methods and members of Protocol1PacketHandler or Protocol2PacketHandler dynamixel::PacketHandler *packetHandler = dynamixel::PacketHandler::getPacketHandler(PROTOCOL_VERSION);

int index = 0; int dxl_comm_result = COMM_TX_FAIL; // Communication result int dxl_goal_position[2] = {DXL_MINIMUM_POSITION_VALUE, DXL_MAXIMUM_POSITION_VALUE}; // Goal position

uint8_t dxl_error = 0; // Dynamixel error int32_t dxl_present_position = 0; // Present position

// Open port if (portHandler->openPort()) { printf("Succeeded to open the port!\n"); } else { printf("Failed to open the port!\n"); printf("Press any key to terminate...\n"); getch(); return 0; }

// Set port baudrate if (portHandler->setBaudRate(BAUDRATE)) { printf("Succeeded to change the baudrate!\n"); } else { printf("Failed to change the baudrate!\n"); printf("Press any key to terminate...\n"); getch(); return 0; }

// Enable Dynamixel Torque dxl_comm_result = packetHandler->write1ByteTxRx(portHandler, DXL_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_ENABLE, &dxl_error); if (dxl_comm_result != COMM_SUCCESS) { std::cout<getTxRxResult(dxl_comm_result)<<std::endl; } else if (dxl_error != 0) { std::cout<getRxPacketError(dxl_error)<<std::endl; } else { printf("Dynamixel has been successfully connected \n"); }

while(1) { printf("Press any key to continue! (or press ESC to quit!)\n"); if (getch() == ESC_ASCII_VALUE) break;

// Write goal position
dxl_comm_result = packetHandler->write4ByteTxRx(portHandler, DXL_ID, ADDR_PRO_GOAL_POSITION, dxl_goal_position[index], &dxl_error);
if (dxl_comm_result != COMM_SUCCESS)
{
  std::cout<<packetHandler->getTxRxResult(dxl_comm_result)<<std::endl;
}
else if (dxl_error != 0)
{
  std::cout<<packetHandler->getRxPacketError(dxl_error)<<std::endl;
}

do
{
  // Read present position
  dxl_comm_result = packetHandler->read4ByteTxRx(portHandler, DXL_ID, ADDR_PRO_PRESENT_POSITION, (uint32_t*)&dxl_present_position, &dxl_error);
  if (dxl_comm_result != COMM_SUCCESS)
  {
    std::cout<<packetHandler->getTxRxResult(dxl_comm_result)<<std::endl;
  }
  else if (dxl_error != 0)
  {
    std::cout<<packetHandler->getRxPacketError(dxl_error)<<std::endl;
  }

  printf("[ID:%03d] GoalPos:%03d  PresPos:%03d\n", DXL_ID, dxl_goal_position[index], dxl_present_position);

}while((abs(dxl_goal_position[index] - dxl_present_position) > DXL_MOVING_STATUS_THRESHOLD));

// Change goal position
if (index == 0)
{
  index = 1;
}
else
{
  index = 0;
}

}

// Disable Dynamixel Torque dxl_comm_result = packetHandler->write1ByteTxRx(portHandler, DXL_ID, ADDR_PRO_TORQUE_ENABLE, TORQUE_DISABLE, &dxl_error); if (dxl_comm_result != COMM_SUCCESS) { std::cout<getTxRxResult(dxl_comm_result)<<std::endl; } else if (dxl_error != 0) { std::cout<getRxPacketError(dxl_error)<<std::endl; }

// Close port portHandler->closePort();

return 0; }` Code.zip