PDA

View Full Version : [Question(s)] Dynamixel Linux SDK



Ctank02
03-08-2013, 10:50 AM
Hi All. I have two questions (btw, I seem to be incapable of figuring out how to add a new line to this editor, so I apologize for the formatting). To make somewhat of a long story short, I am porting the Linux SDK from pure C to C++ to meet the requirements of my lab. The first question I have is does anyone know what the instruction packet has a max size of MAXNUM_TXPARAM(150) + 10? The status packet is similar. It doesn't look like an arbitrary size, but I haven't been able to wrap my head around it (btw, I tried asking on robotis, but got no answer). The 2nd question is about timeout errors. I seem to regularly get timeout errors when communicating with the server from a USB2Dynamixel on Linux. When I say timeout errors, it is getting part of the packet before it times out, so it is setting the status to COMM_RXCORRUPT. Anyone have any ideas to why this is? I'm going to try and do some more testing today to get an idea, but I'm relatively new to all of this, so I'm afraid I may be missing something obvious. Thanks!

jwatte
03-08-2013, 12:29 PM
If you get timeout errors, something is wrong. You may want to hook up a digital oscilloscope or logic analyzer to the bus that the Dynamixels talk on, to compare what goes there to what you see from the USB2Dynamixel.

The maximum size of packets is given by the size field and the parameters you can put into them. If you look at the various packet formats on the Dynamixel communications site, you can calculate the sizes of the worst-case packets and usage scenarios.

In the end, though, I ended up writing my own software, formulating the packets myself. It's not that hard, and lets me have better control over what happens when and where.

Finally, if your lab "requires" that the software is "re-written" from C to C++, then something is seriously wrong with that lab. C is a proper subset of C++, so anything that is C, is also C++.

Ctank02
03-08-2013, 12:45 PM
Thanks for the replies. That being said, when most of the students in the lab are freshman / sophomore undergrads, life isn't always that easy. Sometimes it is easier to change it to something that they are more familiar with. I have an idea on what the problem with the timeouts are, so once I know, I'll report it back here.

tician
03-08-2013, 01:00 PM
Pretty sure the buffer sizes are arbitrary (other libraries use different values), and others have had problems with the sdk erroneously causing timeouts. You could try increasing the timeout delay a bit and see if that helps (it multiplies the number of bytes to be sent/returned by a constant - increase that constant a bit). I know I have had problems with the sdk and embedded-c libraries because it was not happy with the delay between when the servo receives the packet and when the servo eventually starts sending a response packet. Also, the driver settings for the FT232RL sometimes get set to have a high latency (long wait between receiving small packet from the UART and actually creating and sending the USB packet to the PC), but cannot remember how to change them (do not need to recompile, but there is an option file somewhere).




It's the key usually labeled "enter"/"return".

tician
03-08-2013, 01:04 PM
The Robotis C dynamixel sdk allows only a single USB2Dynamixel to be accessed at given time by a given program. Rewriting in C++ enables multiple simultaneous connections within a single program. There is a way to make the C version handle multiple USB2Dynamixel, but it is not a very pretty solution (I've already done it twice for windows, but I wiped it from the Robotis Q&A because it was that poorly implemented).

Ctank02
03-08-2013, 01:11 PM
Thanks Tician. I can't see to get past the stupid timeouts. If anyone knows how to reduce the latency, as tician mentioned, please let me know! Thanks.

KevinO
03-08-2013, 01:31 PM
I had to drop my latency way down in the FTDI driver on the raspberry pi. It's been a few weeks let me go back and see what my steps were. I remeber I set it all the way down to 2. I'm at work right now so I don't have my notes and links in front of me.

jwatte
03-08-2013, 01:33 PM
The first thing you should do is probably to configure your Dynamixels to not wait for a long time before returning data as part of a command. This is a register in each Dynamixel, and you could write/set a very low number (like, 0 or 1,) when you set the ID of the servo, for example.

Secondly, I've had problems before with the Linux USB serial (CDC) drivers. There seems to be something wrong in them, where they will drop data. I think the Dynamixel SDK uses those drivers, because the USB2Dynamixel looks like a USB serial port. I ended up using a custom-programmed Atmega32u4 instead, and send it commands using libusb, rather than going through the serial port driver. If that's not an option for you, perhaps you can still use libusb, and talk directly to the device, rather than let the Linux USB serial driver do it. With luck, that will work more reliably.

KevinO
03-08-2013, 01:34 PM
Here is what I think I did on my raspberry pi / usb2dynamixel robot. You need to run as sudo or be logged in as root.

cat /sys/bus/usb-serial/drivers/ftdi_sio/ttyUSB0/latency_timer

Changing the ttyUSB0 by the ttyUSB that you use.

echo "2" > /sys/bus/usb-serial/drivers/ftdi_sio/ttyUSB0/latency_timer

Ctank02
03-08-2013, 03:49 PM
Thanks Kevin. That was extremely helpful; unfortunately, it was already set to 1 :( I'm 90% sure that the motor is getting my packets (because I can do stuff like turn on and off the LED light, but I still can't get status packets most of the time). I should note, I'm using the code from robotis, so I hoped that they had tested it, but my confidence in their code is blown at this point. EDIT: I'm running Ubuntu 12.10 (not sure if this matters, but figured I should share)

tician
03-08-2013, 04:03 PM
It may just be that I am looking at old versions, but the windows version of "dxl_hal.c" has:

gfRcvWaitTime = (float)(gfByteTransTime*(float)NumRcvByte + 2*LATENCY_TIME + 2.0f);
where the linux version of "dxl_hal.c" has:

gfRcvWaitTime = (float)(gfByteTransTime*(float)NumRcvByte + 5.0f);
where LATENCY_TIME is 16ms, so a big friggin' difference.

Ctank02
03-08-2013, 05:40 PM
OK. I think I've figured out the problem. I've cut the return delay time down all the way, and I've bumped up the timeout formula from their original SDK. I'll keep testing it, but at this point, it appears to work for all of the test cases I've done (including read and writes).

KevinO
03-08-2013, 06:46 PM
When you have time could you go into a bit more detail on what you changed? I'm always tweaking the linux SDK to make it work better for my robot. :)

Ctank02
03-10-2013, 11:50 AM
Hi Kevin,

So, unfortunately, I didn't do anything eloquent. If you recall from the original SDK, there is the following function (mine is slightly edited for C++):



void DynamixelCommunicator::HAL_SetTimeout( int ByteNum ) {
StartTXTime = Clock();
ReceiveWaitTime = (float)(ByteTXTime * (float)ByteNum * 5.0f);
}


That constant of 5.0f, I changed to 25.0f when connected directly to my laptop and to 150.0f when connected directly to my desktop but going through a VM. That being said, ByteNum is always set to six, unless you enter a READ_DATA instruction, at which point it is set to 6 + the size of the parameter you are reading. Once I get some more time, I'm going to change it so that it actually has a better idea of how many bytes it is expecting (the SDK did that by default).

Also, I had to set the return delay time to on the dynamixel AX-12 to 0. What I'd like to do, eventually, is make a transformation function that computes the timeout based on the return delay time. If I make any progress anytime soon, i'll post the information here.