Notice
Recent Posts
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
관리 메뉴

이우의 개발일지

Dynamixel 모터 제어 일기.. XM430-W210 본문

Embeded

Dynamixel 모터 제어 일기.. XM430-W210

공대이우 2024. 11. 11. 22:19

다이나믹셀 XM430 제어 및 통신 오류 발생 원인 분석

현재 제어하고 있는 다이나믹셀 XM430 시리즈는 편리한 SDK와 Wizard 소프트웨어 툴을 통해 상태를 확인하고 컨트롤할 수 있다는 장점이 있는 모터다. 평소 안정적으로 작동해왔으나, 최근 제어 명령을 전달하는 과정에서 처음 보는 오류가 발생하여 원인 분석과 해결을 시도하게 되었다.

 


오류가 떴던 부분들

Failed to send profile velocity values
[ID:001] groupSyncWriteVelocity addParam failed

 

이 오류는 다이나믹셀에 속도 관련 명령을 전송할 때 발생하며, 정상적으로 명령이 수신되면 COMM_SUCCESS라는 메시지가 반환되도록 설정되어 있다. 그러나 이 메시지가 반환되지 않을 경우 오류로 간주되어 위와 같은 메시지가 나타난다.

 

그렇다면 왜? Why? 

 

이 문제의 원인을 파악하기 위해 SW와 HW 문제로 나누어 접근했다. 주된 원인으로는 다음 두 가지 가능성을 염두에 두었다:

 

SW와 HW 문제로 나누어 생각해봤을 때 결론적으로 두 가지 방향으로 접근해볼 수 있었다.

 

 

  • 토크 Off 상태 또는 에러 상황에서 패킷을 보낸 경우
  • 통신 오류(속도 문제)로 인한 명령 누락

 

이 중 문제를 해결하는 과정에서 2번 통신 오류가 주요 원인임을 확인했다. 현재 다이나믹셀에 명령을 약 40msec 간격(0.04초)으로 전달하고 있었는데, 이 짧은 명령 전송 주기가 원인이었다. 초기 설정에서는 40msec 간격으로도 안정적으로 명령을 전달할 수 있었으나, 이번 오류를 계기로 간격이 짧아질수록 다이나믹셀의 명령 처리에 과부하가 발생할 수 있음을 알게 되었다.

 

문제를 해결하기 위해 명령 전송 주기를 40msec에서 더 길게 조정하였고, 이로 인해 오류가 발생하지 않고 정상적으로 명령이 수신되는 것을 확인했다. 다이나믹셀에서 명령을 수신하는 중간에 또 다른 명령이 동시에 들어오면 명령 처리에 오류가 발생하는 것으로 보이며, 특히 특정 시퀀스의 중간에 명령이 꼬이게 되면 이후 모든 명령을 거부하고 통신 오류로 연결된다.

 

결론적으로, 다이나믹셀의 명령 처리에 있어 지나치게 짧은 명령 주기는 통신 오류의 원인이 될 수 있으며, 다이나믹셀이 명령을 정상적으로 수신하고 처리할 수 있는 시간적 여유를 제공하는 것이 중요하다는 점을 확인했다. 이 문제 해결을 통해 시스템의 안정성이 크게 향상되었으며, 앞으로 통신 간격과 명령 우선 순위에 유의하는 방향으로 제어 코드를 최적화할 계획이다.

 

 

다이나믹셀 SDK 제어 코드

bool moveDXLtoDesiredPosition(dynamixel::GroupSyncWrite& groupSyncWriteVelocity, dynamixel::GroupSyncWrite& groupSyncWritePosition, int DXL_ID[], int goal_position[], int velocity)
{
  uint8_t param_profile_velocity[4];
  trans_int2bin_4(param_profile_velocity, velocity);

  // Add Dynamixel profile velocity value to the Syncwrite storage
  for (int i = 0; i < 5; i++)
  {
    if (!groupSyncWriteVelocity.addParam(DXL_ID[i], param_profile_velocity)) 
    {
    fprintf(stderr, "[ID:%03d] groupSyncWriteVelocity addparam failed", DXL_ID[i]);  
    return false;
    }
  }
  // Syncwrite profile velocity
  groupSyncWriteVelocity.txPacket();
  
  for(int i =0 ; i<5; i++)
  {
    uint8_t param_DXL[4];
    trans_int2bin_4(param_DXL, goal_position[i]);
    if (!groupSyncWritePosition.addParam(DXL_ID[i], param_DXL)) { fprintf(stderr, "[ID:%03d] groupSyncWritePosition addparam failed", DXL_ID[0]); return 0; }

  }

  // Syncwrite goal position
  groupSyncWritePosition.txPacket();

  // Clear syncwrite parameter storage
  groupSyncWriteVelocity.clearParam();
  groupSyncWritePosition.clearParam();
  
  return true;

}

 

반응형