20 #define BOOL_EXIT_FAILURE false
32 jointNumbers((unsigned char *) malloc(16 * sizeof (unsigned char))),
34 positions((double *) malloc(numOfAxes * sizeof (double))),
35 speeds((double *) malloc(numOfAxes * sizeof (double))),
37 torques((int *) malloc(numOfAxes * sizeof (int)))
40 jointNumbers[0] = 0x65;
41 jointNumbers[1] = 0x74;
42 jointNumbers[2] = 0x84;
43 jointNumbers[3] = 0x66;
44 jointNumbers[4] = 0x75;
45 jointNumbers[5] = 0x85;
46 jointNumbers[6] = 0x67;
47 jointNumbers[7] = 0x76;
48 jointNumbers[8] = 0x86;
49 jointNumbers[9] = 0x6B;
50 jointNumbers[10] = 0x77;
51 jointNumbers[11] = 0x87;
52 jointNumbers[12] = 0x6A;
53 jointNumbers[13] = 0x68;
54 jointNumbers[14] = 0x69;
55 jointNumbers[15] = 0x6C;
61 ftdi_list_free(&devlist);
74 strcpy(ftdiSetting.
description, config.
check(
"FTDI_DESCRIPTION",
Value(
"FT232R USB UART"),
"Ftdi device description").asString().c_str());
75 strcpy(ftdiSetting.
serial, config.
check(
"FTDI_SERIAL",
Value(
"A7003MhG"),
"Ftdi device serial").asString().c_str());
76 strcpy(ftdiSetting.
manufacturer, config.
check(
"FTDI_MANUFACTURER",
Value(
"FTDI"),
"Ftdi device manufacturer").asString().c_str());
77 ftdiSetting.
baudrate = config.
check(
"baudrate",
Value(57600),
"Specifies the baudrate at which the communication port operates.").asInt32();
78 ftdiSetting.
vendor = config.
check(
"ftdivendor",
Value(0x0403),
"USB device vendor. 0x0403 normally. Can be found by lsusb on linux").asInt32();
79 ftdiSetting.
product = config.
check(
"ftdiproduct",
Value(0x6001),
"USB device product number. 0x6001 normally. Can be found by lsusb on linux").asInt32();
80 ftdiSetting.
flowctrol = config.
check(
"flowctrl",
Value(SIO_DISABLE_FLOW_CTRL),
"flow control to use. Should be SIO_DISABLE_FLOW_CTRL = 0x0, SIO_RTS_CTS_HS = 0x1 << 8, SIO_DTR_DSR_HS = 0x2 << 8, or SIO_XON_XOFF_HS = 0x4 << 8").asInt32();
89 char manufacturer[128], description[128];
93 retCode = ftdi_usb_find_all(&ftdic, &devlist, ftdiSetting.
vendor, ftdiSetting.
product);
115 for (curdev = devlist; curdev != NULL; i++) {
118 if ((retCode = ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, serial, 128)) < 0) {
124 if (strcmp(serial, ftdiSetting.
serial) == 0) {
127 curdev = curdev->next;
130 if (curdev == NULL) {
136 if ((retCode = ftdi_usb_open_dev(&ftdic, curdev->dev)) < 0) {
145 if ((retCode = ftdi_usb_open_dev(&ftdic, curdev->dev)) < 0) {
151 if (ftdic.type == TYPE_R) {
153 if (ftdi_read_chipid(&ftdic, &chipid) == 0) {
164 if ((retCode = ftdi_set_baudrate(&ftdic, ftdiSetting.
baudrate)) != 0)
166 if (ftdi_set_line_property(&ftdic, BITS_8, STOP_BIT_1, NONE) == -1)
168 if (ftdi_setflowctrl(&ftdic, SIO_DISABLE_FLOW_CTRL) == -1)
187 ftdi_usb_purge_buffers(&ftdic);
189 ftdi_usb_reset(&ftdic);
190 ftdi_usb_close(&ftdic);
205 this->initMotorIndex(indexBottle);
209 int DynamixelAX12FtdiDriver::syncSendCommand(
unsigned char id,
unsigned char inst[],
int size,
unsigned char ret[],
int &retSize) {
212 if (!ftdi_usb_purge_buffers(&ftdic)) {
224 bool badAnswer =
false;
225 unsigned char command[16];
226 unsigned char chksum = 0x00;
227 unsigned char header[4];
228 unsigned char body[256];
235 command[3] = size + 1;
238 for (i = 0; i < size; i++) {
239 command[4 + i] = inst[i];
244 command[size + 5 - 1] = ~(chksum + command[2] + command[3]);
246 for (i = 0; i < size + 5; i++) {
250 retCode = ftdi_write_data(&ftdic, command, size + 5);
260 retCode = ftdi_read_data(&ftdic, header, 4);
265 while (retCode == 0);
270 }
else if (retCode < 4) {
275 if (header[0] != 0xFF || header[1] != 0xFF) {
278 }
else if (header[2] !=
id) {
284 retCode = ftdi_read_data(&ftdic, body, header[3]);
285 }
while (retCode == 0);
287 if (retCode != header[3]) {
293 for (i = 0; i < retCode - 1; i++) chksum += body[i];
294 if (body[retCode - 1] != (
unsigned char) ~(chksum + header[2] + header[3])) {
296 yCInfo(
DYNAMIXELAX12FTDIDRIVER,
"Received data with wrong checksum (%X != %X): ", body[retCode - 1], (
unsigned char) ~(chksum + header[2] + header[3]));
299 for (i = 0; i < retCode - 1; i++) {
303 retSize = retCode - 1;
312 for (i = 0; i < 4; i++) {
315 for (i = 0; i < retCode; i++) {
325 ErrorCode DynamixelAX12FtdiDriver::checkAnswerPacket(
unsigned char* packet,
const char*& message) {
327 message =
"Voltage out of operating voltage range!";
331 message =
"Goal position outside angle limits!";
335 message =
"Current temperature outside operating temperature!";
339 message =
"Instruction out of defined range!";
342 if (packet[0] & 16) {
343 message =
"Checksum of instruction package incorrect!";
346 if (packet[0] & 32) {
347 message =
"Specified torque can't control the applied load!";
350 if (packet[0] & 64) {
351 message =
"Undefined instruction or missing Reg_Write instruction!";
363 unsigned char packet[] = {
INST_READ, 0, 1};
365 unsigned char answerPacket[256];
367 const char* errorMessage;
372 packet[1] = param - 100;
381 syncSendCommand(
id, packet, 3, answerPacket, answerSize);
383 if ((errCode = checkAnswerPacket(answerPacket, errorMessage)) !=
OK) {
399 int blankReturnSize = -1;
400 unsigned char blankReturn[] = {0, 0, 0};
402 const int instl = 5 + 1;
404 unsigned char inst[instl] = {
INST_WRITE,
CT_GOAL_POSITION, (
unsigned char) (normalisePosition(ref)&0xFF), (
unsigned char) ((normalisePosition(ref) >> 8) & 0xFF), (
unsigned char) (normaliseSpeed(speed)&0xFF), (
unsigned char) ((normaliseSpeed(speed) >> 8)&0xFF)};
408 return syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
416 for (
int k = 0; k < numOfAxes; k++) {
424 double v = positions[j];
433 for (
int k = 0; k < numOfAxes; k++) {
451 bool tmp_done(
false), all_done(
true);
452 for (
int k = 0; k < numOfAxes; k++)
456 all_done &= tmp_done;
467 }
else if (sp > 114) {
479 for (
int k = 0; k < numOfAxes; k++) {
506 for (
int k = 0; k < numOfAxes; k++) {
531 for (
int i = 0; i < numOfAxes; i++) {
538 int DynamixelAX12FtdiDriver::normalisePosition(
double position) {
542 }
else if (position > 300) {
547 return (
int) (1024 * position / 301);
550 int DynamixelAX12FtdiDriver::normaliseSpeed(
double speed) {
556 }
else if (speed > 114) {
560 return (
int) (1024 * speed / 114 - 1);
564 for (
int k = 0; k < numOfAxes; k++) {
579 for (
int k = 0; k < numOfAxes; k++) {
594 }
else if (
t > 1023) {
599 int blankReturnSize = -1;
600 unsigned char blankReturn[] = {0, 0, 0};
601 const int instl = 3 + 1;
603 unsigned char inst[instl] = {
INST_WRITE,
CT_MAX_TORQUE, (
unsigned char) ((
int)
t & 0xFF), (
unsigned char) (((int)
t << 8) & 0x03)};
605 return syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
616 int blankReturnSize = -1;
617 unsigned char blankReturn[] = {0, 0, 0};
622 ret = syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
624 const char* message =
"";
625 if (checkAnswerPacket(blankReturn, message) ==
OK) {
627 int load = (blankReturn[2]&0X03)*256 + blankReturn[1];
629 load *= (((blankReturn[2] >> 2)&0X01) ? -1 : 1);
641 for (k = 0; k < numOfAxes; k++) {
769 int blankReturnSize = -1;
770 unsigned char blankReturn[] = {0, 0, 0};
775 ret = syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
779 const char* message =
"";
780 if (checkAnswerPacket(blankReturn, message) ==
OK) {
781 pos = ((int) blankReturn[2])*256 + blankReturn[1];
782 *v = ((double) pos)*300.0 / 1024.0;
798 for (k = 0; k < numOfAxes; k++) {
809 int blankReturnSize = -1;
810 unsigned char blankReturn[] = {0, 0, 0};
814 ret = syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
817 const char* message =
"";
818 if (checkAnswerPacket(blankReturn, message) ==
OK) {
820 speed = (blankReturn[2]&0X03)*0xFF + blankReturn[1];
823 speed *= (((blankReturn[1] >> 2)&0X01) ? -1 : 1);
825 *sp = speed * 113 / 1024 + 1;
836 for (k = 0; k < numOfAxes; k++) {
851 bool DynamixelAX12FtdiDriver::initMotorIndex(
yarp::os::Bottle *sensorIndex) {
852 int s = sensorIndex->
size() - 1;
858 unsigned char *tmp = NULL;
859 tmp = (
unsigned char *) realloc(jointNumbers, numOfAxes *
sizeof (
unsigned char));
867 tmpp = (
double *) realloc(positions, numOfAxes *
sizeof (
double));
875 tmps = (
double *) realloc(speeds, numOfAxes *
sizeof (
double));
883 tmpt = (
int *) realloc(torques, numOfAxes *
sizeof (
int));
890 for (
int i = 0; i < numOfAxes; i++) {
891 jointNumbers[i] = (
unsigned char) (sensorIndex->
get(i + 1).
asInt32());
899 for(
int j=0; j<n_joint; j++)
909 for(
int j=0; j<n_joint; j++)
919 bool tmp_joint(
false), tmp_device(
true);
920 for(
int j=0; j<n_joint; j++)
923 tmp_device &= tmp_joint;
932 for(
int j=0; j<n_joint; j++)
942 for(
int j=0; j<n_joint; j++)
952 for(
int j=0; j<n_joint; j++)
962 for(
int j=0; j<n_joint; j++)
972 for(
int j=0; j<n_joint; j++)