by DFMcCoy » Tue Jun 07, 2011 9:26 pm
by DFMcCoy
Tue Jun 07, 2011 9:26 pm
Hello,
I'm working with a team on a project that uses 6 Dynamixel servos in a daisy chain configuration. The servos are a combination of the RX-64s and the RX-28s so in order to communicate with all the servos one RS-485 interface is required.
The end goal of my project is to realize a high level motion control of an inexpensive custom robotic arm. In order to do that I need a tight control loop that is capable of reading 6 values back from all 6 servos at a rate of 100Hz. Unfortunately I have been running into latency issues.
Initially I tried to use the USB2Dynamixel device (
http://support.robotis.com/en/product/a ... manual.htm). I noticed a rather large delay when reading each sensor value from the entire chain. The delay ranged from 10ms to around 30ms for each individual sensor reading. I found it was related to the USB driver in Linux. So following the instruction on the Robotis website (
http://support.robotis.com/en/software/ ... _linux.htm) I rebuilt the kernel module reducing the FTDI serial buffer timeout from 16ms to 1ms. I got a small improvement, but even if there were Ideal conditions If I were to read 6 sensor values from 6 different servos with 1ms latency to request the data and 1ms latency to read the data I'm looking at a 72ms delay for reading the entire set of sensor values.
We tried to use the Grid Power Net485 (
http://www.gridconnect.com/net485.html) so that we could circumvent any USB timeout, but found that we were averaging about 30ms per individual read.
Lastly we got a hold of the cm-700 from Robotis (
http://support.robotis.com/en/product/a ... manual.htm) which is a micro controller that communicates with a Linux host through its own USB to serial connection. I tried to use the initial scripting interface that came with the MCU but it was rather limited in our application. I found that it was possible to re-program the cm-700. So I wrote a program that reads from all the servos at a rate of 1M baudrate, and communicates with the host at the same speed.
At this rate,
It takes 8 bytes to request the data from the individual servo, with a start bit of 1us, and a "stop bit" of 1us therefore it takes approximately 10us * 8 = 80us to request a read from a servo, 1 us for response (this was verified with an oscilloscope capture on a servo) and 7 bytes, or 70us to read the data back. total it takes approximately 151us to read a value from a servo. We have 6 servos and 6 values, it should take nearly 1ms to read all the values from the servos. I created a simply algorithmic byte array in order to code the data to return to the host all the data in a simple format. The format is as follows.
Status
Servo Response SS[# of servos(1)][# of sensors(1)][Servo ID(2)][Address(2)][Value(4)]...'\n'
EXAMPLE: SS220000123402432102000001022222
Number of servos 2
Number of sensors 2
Servo ID 00
Sensor Address 00
Sensor Value 1234
Sensor Address 02
Sensor Value 4321
Servo ID 02
Sensor Adderss 00
Sensor Value 0001
Sensor Address 02
Sensor Value 2222
The total number of bytes sent to the host = 2 + 1 + 1 + Servo Count * ( 2 + Sensor Count * (2 + 4)) + 1
For the 6 servos reading the 6 sensors, there will be 233 bytes.
Given it takes 10us to send 1 byte of data then it should take around 2.33 ms + 1ms (possible usb delay) for an entire read. I have disregarded the latency issued by the MCU because it is relatively small.
Finally the values that I should be reading are something on the order of about 4.5 - 5ms for an entire packet of servo values. If the servo is programmed to read data from the servos and then turn around and write the data to the host I should be able to accomplish 200 samples per second.
Is there any way to get a faster read time than this?
Dave
Hello,
I'm working with a team on a project that uses 6 Dynamixel servos in a daisy chain configuration. The servos are a combination of the RX-64s and the RX-28s so in order to communicate with all the servos one RS-485 interface is required.
The end goal of my project is to realize a high level motion control of an inexpensive custom robotic arm. In order to do that I need a tight control loop that is capable of reading 6 values back from all 6 servos at a rate of 100Hz. Unfortunately I have been running into latency issues.
Initially I tried to use the USB2Dynamixel device (
http://support.robotis.com/en/product/a ... manual.htm). I noticed a rather large delay when reading each sensor value from the entire chain. The delay ranged from 10ms to around 30ms for each individual sensor reading. I found it was related to the USB driver in Linux. So following the instruction on the Robotis website (
http://support.robotis.com/en/software/ ... _linux.htm) I rebuilt the kernel module reducing the FTDI serial buffer timeout from 16ms to 1ms. I got a small improvement, but even if there were Ideal conditions If I were to read 6 sensor values from 6 different servos with 1ms latency to request the data and 1ms latency to read the data I'm looking at a 72ms delay for reading the entire set of sensor values.
We tried to use the Grid Power Net485 (
http://www.gridconnect.com/net485.html) so that we could circumvent any USB timeout, but found that we were averaging about 30ms per individual read.
Lastly we got a hold of the cm-700 from Robotis (
http://support.robotis.com/en/product/a ... manual.htm) which is a micro controller that communicates with a Linux host through its own USB to serial connection. I tried to use the initial scripting interface that came with the MCU but it was rather limited in our application. I found that it was possible to re-program the cm-700. So I wrote a program that reads from all the servos at a rate of 1M baudrate, and communicates with the host at the same speed.
At this rate,
It takes 8 bytes to request the data from the individual servo, with a start bit of 1us, and a "stop bit" of 1us therefore it takes approximately 10us * 8 = 80us to request a read from a servo, 1 us for response (this was verified with an oscilloscope capture on a servo) and 7 bytes, or 70us to read the data back. total it takes approximately 151us to read a value from a servo. We have 6 servos and 6 values, it should take nearly 1ms to read all the values from the servos. I created a simply algorithmic byte array in order to code the data to return to the host all the data in a simple format. The format is as follows.
Status
Servo Response SS[# of servos(1)][# of sensors(1)][Servo ID(2)][Address(2)][Value(4)]...'\n'
EXAMPLE: SS220000123402432102000001022222
Number of servos 2
Number of sensors 2
Servo ID 00
Sensor Address 00
Sensor Value 1234
Sensor Address 02
Sensor Value 4321
Servo ID 02
Sensor Adderss 00
Sensor Value 0001
Sensor Address 02
Sensor Value 2222
The total number of bytes sent to the host = 2 + 1 + 1 + Servo Count * ( 2 + Sensor Count * (2 + 4)) + 1
For the 6 servos reading the 6 sensors, there will be 233 bytes.
Given it takes 10us to send 1 byte of data then it should take around 2.33 ms + 1ms (possible usb delay) for an entire read. I have disregarded the latency issued by the MCU because it is relatively small.
Finally the values that I should be reading are something on the order of about 4.5 - 5ms for an entire packet of servo values. If the servo is programmed to read data from the servos and then turn around and write the data to the host I should be able to accomplish 200 samples per second.
Is there any way to get a faster read time than this?
Dave