The intent of this code is to be clear and easy to understand, it not pretend to be the best code to do the job.
This method create the command to write the AX-12+ position :
[sourcecode language="cpp"]
int Dynamixel::getSetAX12PositionCommand(byte id, short goal)
{
int pos = 0;
byte numberOfParameters = 0;
//OXFF 0XFF ID LENGTH INSTRUCTION PARAMETER1 …PARAMETER N CHECK SUM
buffer[pos++] = 0xff;
buffer[pos++] = 0xff;
buffer[pos++] = id;
// bodyLength
buffer[pos++] = 0; //place holder
//the instruction, query => 3
buffer[pos++] = 3;
// goal registers 30 and 31
buffer[pos++] = 0x1E;// 30;
//bytes to write
byte hexH = 0;
byte hexL = 0;
toHexHLConversion(goal, &hexH, &hexL);
buffer[pos++] = hexL;
numberOfParameters++;
buffer[pos++] = hexH;
numberOfParameters++;
// bodyLength
buffer[3] = (byte)(numberOfParameters + 3);
byte checksum = checkSumatory(buffer, pos);
buffer[pos++] = checksum;
return pos;
}
int Dynamixel::setPosition(SerialPort *serialPort, int idAX12, int position)
{
int error=0;
int n=getSetAX12PositionCommand(idAX12, position);
long l=serialPort->sendArray(buffer,n);
Sleep(10);
memset(bufferIn,0,BufferSize);
n=serialPort->getArray(bufferIn, 8);
if (n>4 && bufferIn[4] == 0)
printf("nid=<%i> set at pos=<%i>n", idAX12, position);
else {
error=-1;
printf("nid=<%i> error: <%i>n", idAX12, bufferIn[4]);
bf(bufferIn, n);
}
return error;
}
[/sourcecode]
Hi (again) :) assume I have four AX 12 to control at 50Hz. As I have to send one instruction at a time, it means that I should have a maximum of 1000/50/4 = 5ms between two instructions. However (having set each AX 12's return delay time to 0 and return status level to 0), if I do so, after a short period (a few seconds) the servos get "stuck" with the last instruction and won't listen to any further instruction...! I assume this is related to the half-duplex UART, so I should "force" the direction to TX. I do not see any of this in your Serial class. Any hints? Thanks a lot
ResponderEliminarActually there is the Sync_write instruction. But if I go beyond 10-20Hz, at some point the servos freeze and remain in the last "read" state...Is it normal?
ResponderEliminarYes (AFAIK) you should add a delay, about 3-8 ms for wired connections, and until 30-40 ms for wireless connections (BT. Zig).
ResponderEliminarThat sounds better! However, in wheel mode, wired, if I put a delay inferior to approx. 40ms between my SYNCWRITE instructions, at some point the servos get stuck (for example, at speed 800) and won't read anything more... :|
ResponderEliminarany ideas?
Maybe this is related to the continuous rotation mode, I should try such rates (8ms) for position control.
But if you tell me that you succeeded with a delay of 8ms and with the code you posted, there is hope for me! :D
"Programatically" I have used mainly position control, not continuous mode, but I think that both should work in a similar way. Sometimes I have had errors sabotaging my work :)
ResponderEliminarIn a few days I want to upload several programs source code I hope could help you.