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++)
bool NOT_YET_IMPLEMENTED(const char *txt)
#define BOOL_EXIT_FAILURE
const yarp::os::LogComponent & DYNAMIXELAX12FTDIDRIVER()
#define AX12_BROADCAST_ID
defines for AX12 general ids
#define MOTION_COMPLETION_TOLERANCE
#define CT_PRESENT_POSITION
bool setRefAccelerations(const double *accs) override
not implemented
bool resetTorquePid(int j)
bool getEncoderSpeed(int j, double *sp) override
Read the istantaneous speed of an axis.
bool setTorquePid(int j, const Pid &pid)
bool getTorquePid(int j, Pid *pid)
bool setTorqueOffset(int j, double v)
bool close() override
Close device Closes the device and shuts down connection.
bool getTorque(int j, double *t) override
Get the value of the torque on a given joint (this is the feedback if you have a torque sensor).
bool setTorqueErrorLimits(const double *limits)
bool setTorque(int j, double t)
virtual int sendCommand(unsigned char id, unsigned char inst[], int size, unsigned char ret[], int &retSize)
Send instruction to device Send an instruction to a device of given ID.
bool setTorquePids(const Pid *pids)
bool getBemfParam(int j, double *bemf)
virtual int readParameter(unsigned char id, unsigned char param)
Read parameter from motor Requests the value of a parameter from motor.
bool resetEncoder(int j) override
Reset encoder, single joint.
bool getTorquePidOutputs(double *outs)
bool setTorques(const double *t)
bool getRefTorque(int j, double *t) override
Get the reference value of the torque for a given joint.
bool setRefAcceleration(int j, double acc) override
not implemented
bool setEncoders(const double *vals) override
Set the value of all encoders.
bool getEncoder(int j, double *v) override
Get the angle of servo.
bool configure(yarp::os::Searchable &config) override
Configure device online Configures parts of the device that can be configures online.
bool getTorqueError(int j, double *err)
bool setRefTorque(int j, double t) override
Set the reference value of the torque for a given joint.
bool getRefSpeeds(double *spds) override
Get reference speed of all joints.
bool getEncoderAccelerations(double *accs) override
Read the instantaneous acceleration of all axes.
bool setEncoder(int j, double val) override
Set the value of the encoder for a given joint.
bool getTorqueErrorLimits(double *limits)
bool setRefTorques(const double *t) override
Set the reference value of the torque for all joints.
bool getEncoders(double *encs) override
Read the position of all axes.
bool getRefSpeed(int j, double *ref) override
Get reference speed for a joint.
bool checkMotionDone(int j, bool *flag) override
Check if the current trajectory is terminated.
bool getEncoderSpeeds(double *spds) override
Read the instantaneous speed of all axes.
bool disableTorquePid(int j)
bool open(yarp::os::Searchable &config) override
Open device Opens and configures the device.
DynamixelAX12FtdiDriver()
Constructor Initializes handle but doesn't open channel yet.
virtual ~DynamixelAX12FtdiDriver()
Destructor Closes connection and destroys device object.
bool getTorqueRange(int j, double *min, double *max) override
Get the full scale of the torque sensor of a given joint.
bool getTorqueErrors(double *errs)
bool getAxes(int *ax) override
Get the number of controlled axes.
bool getRefAccelerations(double *accs) override
not implemented
bool resetEncoders() override
Reset encoders.
bool setTorqueErrorLimit(int j, double limit)
bool enableTorquePid(int j)
bool setBemfParam(int j, double bemf)
bool getEncoderAcceleration(int j, double *spds) override
Read the instantaneous acceleration of an axis.
bool setRefSpeeds(const double *spds) override
Set reference speed on all joints.
bool getTorques(double *t) override
Get the value of the torque for all joints (this is the feedback if you have torque sensors).
bool stop() override
Stop motion, multiple joints.
bool positionMove(int j, double ref) override
bool getRefTorques(double *t) override
Get the reference value of the torque for all joints.
bool getTorqueErrorLimit(int j, double *limit)
bool getTorquePids(Pid *pids)
bool getRefAcceleration(int j, double *acc) override
not implemented
bool getTorqueRanges(double *min, double *max) override
Get the full scale of the torque sensors of all joints.
bool getTorquePidOutput(int j, double *out)
bool relativeMove(int j, double delta) override
Set relative position.
bool setRefSpeed(int j, double sp) override
Set reference speed for a joint, this is the speed used during the interpolation of the trajectory.
FtdiDeviceSettings contains information to identify specific device Such a device can contain informa...
unsigned int write_chunksize
unsigned int read_chunksize
Contains the parameters for a PID.
A simple collection of objects that can be described and transmitted in a portable way.
size_type size() const
Gets the number of elements in the bottle.
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
A base class for nested structures that can be searched.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
A single value (typically within a Bottle).
virtual std::int32_t asInt32() const
Get 32-bit integer value.
virtual Bottle * asList() const
Get list value.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCTrace(component,...)
#define yCDebug(component,...)
#define YARP_LOG_COMPONENT(name,...)
An interface for the device drivers.
An interface to the operating system, including Port based communication.