17 #define BOOL_EXIT_FAILURE false
29 jointNumbers((unsigned char *) malloc(16 * sizeof (unsigned char))),
31 positions((double *) malloc(numOfAxes * sizeof (double))),
32 speeds((double *) malloc(numOfAxes * sizeof (double))),
34 torques((int *) malloc(numOfAxes * sizeof (int)))
37 jointNumbers[0] = 0x65;
38 jointNumbers[1] = 0x74;
39 jointNumbers[2] = 0x84;
40 jointNumbers[3] = 0x66;
41 jointNumbers[4] = 0x75;
42 jointNumbers[5] = 0x85;
43 jointNumbers[6] = 0x67;
44 jointNumbers[7] = 0x76;
45 jointNumbers[8] = 0x86;
46 jointNumbers[9] = 0x6B;
47 jointNumbers[10] = 0x77;
48 jointNumbers[11] = 0x87;
49 jointNumbers[12] = 0x6A;
50 jointNumbers[13] = 0x68;
51 jointNumbers[14] = 0x69;
52 jointNumbers[15] = 0x6C;
58 ftdi_list_free(&devlist);
71 strcpy(ftdiSetting.
description, config.
check(
"FTDI_DESCRIPTION",
Value(
"FT232R USB UART"),
"Ftdi device description").asString().c_str());
72 strcpy(ftdiSetting.
serial, config.
check(
"FTDI_SERIAL",
Value(
"A7003MhG"),
"Ftdi device serial").asString().c_str());
73 strcpy(ftdiSetting.
manufacturer, config.
check(
"FTDI_MANUFACTURER",
Value(
"FTDI"),
"Ftdi device manufacturer").asString().c_str());
74 ftdiSetting.
baudrate = config.
check(
"baudrate",
Value(57600),
"Specifies the baudrate at which the communication port operates.").asInt32();
75 ftdiSetting.
vendor = config.
check(
"ftdivendor",
Value(0x0403),
"USB device vendor. 0x0403 normally. Can be found by lsusb on linux").asInt32();
76 ftdiSetting.
product = config.
check(
"ftdiproduct",
Value(0x6001),
"USB device product number. 0x6001 normally. Can be found by lsusb on linux").asInt32();
77 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();
86 char manufacturer[128], description[128];
90 retCode = ftdi_usb_find_all(&ftdic, &devlist, ftdiSetting.
vendor, ftdiSetting.
product);
112 for (curdev = devlist; curdev != NULL; i++) {
115 if ((retCode = ftdi_usb_get_strings(&ftdic, curdev->dev, manufacturer, 128, description, 128, serial, 128)) < 0) {
121 if (strcmp(serial, ftdiSetting.
serial) == 0) {
124 curdev = curdev->next;
127 if (curdev == NULL) {
133 if ((retCode = ftdi_usb_open_dev(&ftdic, curdev->dev)) < 0) {
142 if ((retCode = ftdi_usb_open_dev(&ftdic, curdev->dev)) < 0) {
148 if (ftdic.type == TYPE_R) {
150 if (ftdi_read_chipid(&ftdic, &chipid) == 0) {
161 if ((retCode = ftdi_set_baudrate(&ftdic, ftdiSetting.
baudrate)) != 0) {
164 if (ftdi_set_line_property(&ftdic, BITS_8, STOP_BIT_1, NONE) == -1) {
167 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++) {
296 if (body[retCode - 1] != (
unsigned char) ~(chksum + header[2] + header[3])) {
298 yCInfo(
DYNAMIXELAX12FTDIDRIVER,
"Received data with wrong checksum (%X != %X): ", body[retCode - 1], (
unsigned char) ~(chksum + header[2] + header[3]));
301 for (i = 0; i < retCode - 1; i++) {
305 retSize = retCode - 1;
314 for (i = 0; i < 4; i++) {
317 for (i = 0; i < retCode; i++) {
327 ErrorCode DynamixelAX12FtdiDriver::checkAnswerPacket(
unsigned char* packet,
const char*& message) {
329 message =
"Voltage out of operating voltage range!";
333 message =
"Goal position outside angle limits!";
337 message =
"Current temperature outside operating temperature!";
341 message =
"Instruction out of defined range!";
344 if (packet[0] & 16) {
345 message =
"Checksum of instruction package incorrect!";
348 if (packet[0] & 32) {
349 message =
"Specified torque can't control the applied load!";
352 if (packet[0] & 64) {
353 message =
"Undefined instruction or missing Reg_Write instruction!";
365 unsigned char packet[] = {
INST_READ, 0, 1};
367 unsigned char answerPacket[256];
369 const char* errorMessage;
374 packet[1] = param - 100;
383 syncSendCommand(
id, packet, 3, answerPacket, answerSize);
385 if ((errCode = checkAnswerPacket(answerPacket, errorMessage)) !=
OK) {
401 int blankReturnSize = -1;
402 unsigned char blankReturn[] = {0, 0, 0};
404 const int instl = 5 + 1;
406 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)};
410 return syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
418 for (
int k = 0; k < numOfAxes; k++) {
427 double v = positions[j];
437 for (
int k = 0; k < numOfAxes; k++) {
456 bool tmp_done(
false), all_done(
true);
457 for (
int k = 0; k < numOfAxes; k++)
462 all_done &= tmp_done;
473 }
else if (sp > 114) {
485 for (
int k = 0; k < numOfAxes; k++) {
513 for (
int k = 0; k < numOfAxes; k++) {
538 for (
int i = 0; i < numOfAxes; i++) {
546 int DynamixelAX12FtdiDriver::normalisePosition(
double position) {
550 }
else if (position > 300) {
555 return (
int) (1024 * position / 301);
558 int DynamixelAX12FtdiDriver::normaliseSpeed(
double speed) {
564 }
else if (speed > 114) {
568 return (
int) (1024 * speed / 114 - 1);
572 for (
int k = 0; k < numOfAxes; k++) {
587 for (
int k = 0; k < numOfAxes; k++) {
603 }
else if (
t > 1023) {
608 int blankReturnSize = -1;
609 unsigned char blankReturn[] = {0, 0, 0};
610 const int instl = 3 + 1;
612 unsigned char inst[instl] = {
INST_WRITE,
CT_MAX_TORQUE, (
unsigned char) ((
int)
t & 0xFF), (
unsigned char) (((int)
t << 8) & 0x03)};
614 return syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
625 int blankReturnSize = -1;
626 unsigned char blankReturn[] = {0, 0, 0};
631 ret = syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
633 const char* message =
"";
634 if (checkAnswerPacket(blankReturn, message) ==
OK) {
636 int load = (blankReturn[2]&0X03)*256 + blankReturn[1];
638 load *= (((blankReturn[2] >> 2)&0X01) ? -1 : 1);
650 for (k = 0; k < numOfAxes; k++) {
779 int blankReturnSize = -1;
780 unsigned char blankReturn[] = {0, 0, 0};
785 ret = syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
789 const char* message =
"";
790 if (checkAnswerPacket(blankReturn, message) ==
OK) {
791 pos = ((int) blankReturn[2])*256 + blankReturn[1];
792 *v = ((double) pos)*300.0 / 1024.0;
809 for (k = 0; k < numOfAxes; k++) {
820 int blankReturnSize = -1;
821 unsigned char blankReturn[] = {0, 0, 0};
825 ret = syncSendCommand(jointNumbers[j], inst, instl, blankReturn, blankReturnSize);
828 const char* message =
"";
829 if (checkAnswerPacket(blankReturn, message) ==
OK) {
831 speed = (blankReturn[2]&0X03)*0xFF + blankReturn[1];
834 speed *= (((blankReturn[1] >> 2)&0X01) ? -1 : 1);
836 *sp = speed * 113 / 1024 + 1;
847 for (k = 0; k < numOfAxes; k++) {
863 bool DynamixelAX12FtdiDriver::initMotorIndex(
yarp::os::Bottle *sensorIndex) {
864 int s = sensorIndex->
size() - 1;
870 unsigned char *tmp = NULL;
871 tmp = (
unsigned char *) realloc(jointNumbers, numOfAxes *
sizeof (
unsigned char));
879 tmpp = (
double *) realloc(positions, numOfAxes *
sizeof (
double));
887 tmps = (
double *) realloc(speeds, numOfAxes *
sizeof (
double));
895 tmpt = (
int *) realloc(torques, numOfAxes *
sizeof (
int));
902 for (
int i = 0; i < numOfAxes; i++) {
903 jointNumbers[i] = (
unsigned char) (sensorIndex->
get(i + 1).
asInt32());
911 for(
int j=0; j<n_joint; j++)
921 for(
int j=0; j<n_joint; j++)
931 bool tmp_joint(
false), tmp_device(
true);
932 for(
int j=0; j<n_joint; j++)
935 tmp_device &= tmp_joint;
944 for(
int j=0; j<n_joint; j++)
954 for(
int j=0; j<n_joint; j++)
964 for(
int j=0; j<n_joint; j++)
974 for(
int j=0; j<n_joint; j++)
984 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.