...
POST No. 2590627
아두이노 쉴드 라이브러리
2019-09-05 20:36:33 hiatom

안녕하세요. 아두이노 쉴드라이브러리를 이용해 다이나믹셀을 제어하고 있습니다.

컴퓨터에서 시리얼통신으로 데이터를 받아 다이나믹셀을 제어 하고있는데, setGoalPosition() 을 이용하여 제어하고 있습니다.

총 6개의 다이나믹셀을 제어하는데, setGoalPosition()을 6번 호출하면 시리얼 통신으로 수신받은 패킷이 손실되네요.

setGoalPosition()을 6번 호출 하지 않으면 제대로 받아집니다.

 

setGoalPosition() 한번 호출할때마다 시간을 재어보니 20ms 정도 걸려서 그런거같은데 (6번 호출하니 120ms 정도) 

setGoalPosition()의 시간을 줄일수 있는 방법은 없을까요? 

 

* 참고사항

pc와 아두이노간의 통신속도는 115200 baudrate이고,

아두이노와 다이나믹셀간의 통신속도는 57600 baudrate입니다.

 

감사합니다.

2019-09-05 20:36:33
hiatom
2019-09-06 10:18:15 유기웅
안녕하세요.

우선 질문 내용중에 "컴퓨터에서 시리얼통신으로 데이터를 받아 다이나믹셀을 제어 하고있는데"가 의미하는 바를 알고 싶고,
"시리얼 통신으로 수신받은 패킷이 손실"이라는 것도 확인하고 싶습니다.

내용만으로 유추했을 때는, 동작 시간이 늘어날 요소가 많기 때문에, 보다 정확한 정보가 필요합니다.

그리고, 단순한 이야기이지만, 패킷을 시리얼로 확인하면서까지 사용한다면,
각각의 통신속도를 높이면 그만큼 동작 시간이 줄어듭니다.

감사합니다.

comment
2019-09-06 13:01:40 hiatom
컴퓨터에서 inverse Kinematic을 계산하여, 총 6개의 motor angle을 아두이노에서 read합니다.
이 때 데이터는, structure로, 32 bytes로 보냅니다.
그리고 serial.readBytes를 이용하여 32bytes를 받고, 이를 parsing하여 시간을 측정해보니 3ms 정도가 걸렸습니다. 이 작업만 수행하면 문제없이 read를 하고 있구요.

이 작업 뒤에 delay를 주어 몇 ms 까지 작업을 해줄수 있는지 실험해보니 30ms걸리는 연산까지는 문제없이 read 할수 있을거라 생각했습니다.

우선 해당 serial read하는 작업 뒤에, for문을 이용하여 6개의 다이나믹셀을 joint angle 정보를 setGoalPosition을 이용하여 제어합니다.
이 작업이 끝난뒤에는 약 125ms 이상이 걸리게 되는데요.
setGoalPosition 호출 전과 호출 후를 비교해보니 20ms 차이가 발생하더라구요.

패킷 손실은 structure data를 받아보니, 0~360.0 사이의 값이 나와야하는데, ovf 가 뜨길래
setGoalPosition을 호출할경우 loop속도가 받쳐주지 못하여 시리얼 통신의 패킷이 손실된다고 생각했습니다.

처음에 사용한 코드는 대략적으로
1. serial로 32바이트 데이터를 받고,
2. 32바이트 데이터를 float 데이터로 parsing한후
3. structure data의 시작과 끝(header?)이 제가 규약한게 맞는지 확인한뒤
4. 다이나믹셀 6개를 for문을 이용해 제어합니다.
5. 다시 1로 돌아갑니다.

현재는 시리얼 데이터 수신에 문제가 있어서, 제가 규약한 structure data가 들어올때까지 반복한뒤,
다이나믹셀을 제어하고 있습니다.

그래도 다이나믹셀을 제어하는 loop가 7~8Hz 밖에 안나와서 setGoalPosition의 처리 속도를 줄이면 더 높은 loop 속도를 만들수 있을거라 생각하고 있습니다.
2019-09-06 13:01:40
hiatom
2019-09-06 13:01:55 hiatom
setGoalPosition을 한번 호출하면 20ms 지연이 발생한다는 것이고,
모터 6개를 제어하기 때문에
약 120ms의 시간이 지연되는 상황입니다.
2019-09-06 13:01:55
hiatom
2019-09-06 10:18:15
ykw4463
2019-09-06 13:36:51 유기웅

안녕하세요.

 

자세한 설명 감사합니다.

 

Dynamixel2Arduino (약칭, D2A) 라이브러리는 사용자가 쉽게 사용할 수 있는 API를 제공하는데 목적이 있습니다.
따라서, 통신속도를 올리거나 CPU속도가 빨라지지 않는 이상은 시간을 단축시키기 어렵습니다.

그리고 6개의 모터에 대해 하나하나 명령을 보내는 것 보다 syncWrite 기능을 사용하는 것이 DYNAMIXEL을 더 효율적으로 사용할 수 있습니다.
다만, 이 기능을 사용하려면, 쉬운 API를 포기해야하며,
예제는 D2A 예제의 "advanced" -> "sync_read_write_raw" 예제를 참조해주세요.
추가로, 이 예제에서 사용하는 Master API를 사용하면, 복잡한 처리가 빠지게 됨으로써, 속도가 향상될 것으로 기대됩니다.

아래 링크를 참조해주세요.

감사합니다.
comment
2019-09-06 13:43:29 hiatom
상세한 답변 감사드립니다.
한번 시도해보겠습니다.
2019-09-06 13:43:29
hiatom
2019-09-16 08:39:38 hiatom
해당문제 해결했습니다.
시간을 측정해보니까 bulkRead 호출에서 많은 시간을 잡아먹네요.
감사합니다.
2019-09-16 08:39:38
hiatom
2019-09-06 13:36:51
ykw4463
답변달기
웹에디터 시작 웹 에디터 끝