Reduce sampling time

Problem Description:
I am trying to achieve a sampling time of 1 millisecond. Currently, if I want to control three motors at the same time, the loop duration is 0.008 seconds. Due to this limitation, I am currently using a sampling time of 0.01 seconds for my experiment. Unfortunately, this sampling time is too long for the control method I want to use to efficiently control the openManipulator -x and ensure accurate tracking.

In my opinion, the main problem is that reading and writing the motors takes too much time. As you can see in the attached picture, I have included a small example code segment to explain my problem in more detail. Even in this small example where only one motor is used, the loop duration is 0.0012 seconds.
loop_duration

Steps taken so far:

  • I have set the baud rate to 2 Mbps (2,000,000).

  • The return delay time was set to 0 µs.

  • I used the fastSyncRead function for communication.

Hardware and software used:

  • I use three Dynamixel motors of the type XM430-W350-T.
  • For control and communication I use the DYNAMIXEL Shield
  • Arduino Mega 2560 is used as the microcontroller
  • To determine the position of the motors I use an LN-101
  • The programming is done via the Arduino IDE over Windows 10

Maybe someone has more ideas on how to increase the reading and writing speed of the motors to reduce the sampling time to 0.001 seconds?

I don’t think that the LN-101 can go to 2 Mbps for baud rate. You can try the U2D2 if you have one.

You can also try a faster controller like Portenta H 7 or OpenRB-150 or RPI-4B or Jetson Nano, for faster program execution at run time.

Have you already adjusted your USB serial latency? The lowest possible setting is 1Millisecond, so you won’t be able to get any faster than that without specialized setup, but this can hopefully get you closer to your desired response times.

Yes, you are right. Problems occur at a baud rate of 2 Mbps, and this not only affects the connection with LN-101, but also with U2D2.
Unfortunately, I do not have access to Portenta H7, OpenRB-150, RPI-4B or Jetson Nano. Especially with Portenta H7, RPI-4B and Jetson Nano I am not sure how I could connect them to my openManipulator-x as they don’t seem to have a TTL interface.
As for OpenRB-150, I tried twice and it was defective both times, so I am rather reluctant to try again. (see my forum post for more information)

Unfortunately that didn’t help, the loop duration is still at 0.0082s.

It strikes me that your proposed solutions so far have mainly focused on speeding up data transmission. However, my approach was more along the lines that the motors themselves take too much time to deliver the information they need. In my opinion, the problem is not with the Arduino Mega or the LN-101, but rather that the motors need a certain amount of time to provide their position information.

However, if you are right and the main problem is the Arduino Mega or LN-101, a possible solution could be to temporarily store the position values on an external storage medium such as an SD card and retrieve them later instead of working in real time.
Of course, it would be ideal to monitor the performance of the controller in real time, but if the delay in data transmission is the main problem and the sampling rate is affected as a result, temporarily storing the values could be an acceptable solution.

I have assumed so far that the motors themselves are the problem when it comes to delivering the information in time. How do you see this?

Speeding up DYNAMIXEL communication on your Arduino board can be accomplished by using the Bulk read and write commands to send instruction packets. The Bulk send command doesn’t wait for any returned response packets, and the bulk read command condenses the response into a single status packet. But if using these commands still doesn’t get your response time low enough, then it comes down to the internal loop rate of the DYNAMIXEL servos being slower than your target speed, which can’t be sped up or altered.

I agree with @Jonathon about implementing Bulk read/write first. I thought that FastSyncRead is faster then BulkRead?

The reasons that I mentioned RPi-4B or Jetson Nano because they have plenty of USB Ports so that you can use the U2D2 with the usual 1 ms delay setting and Bulk read/write + FastSyncRead as before, but you will have to use the DXL SDK directly in C/C++. The U2D2 also allows you to set your XM-430 to 4.0 mbps. Furthermore, from my experiences with RPi4B and Jetson Nano: when I used 64 bit OS, I got a boost in performance 4-5 times more than 32 bit OS - perhaps I was more constrained by “number-crunching” than “actuator I/O bound” in my projects. So perhaps this would be enough to get to your 1 ms I/O goal? Lastly, Jetson Nano (or Jetson Orin Nano) is way better at “number crunching” than RPi4B from my experiences, if you ever go the RPi-4B/Jetson Nano route.

Of course, the big question for you is that can you switch to RPi4B/Jetson-Nano, considering the other Arduino Hardware that you may need for your current robot?

With the Portenta H7, you do get a higher MCU performance, but you will have to use the DXL MKR Shield.

My Arduino book has a whole chapter about using the Portenta H7.

https://www.amazon.com/Using-ARDUINO-ROBOTIS-Systems-Ngoc-ebook/dp/B0BPXGQ6YX

However ROBOTIS does not recommend to go beyond 1 Mbps for DXL baud rate with the DXL MKR Shield.

image

So overall, I think that you may have to make some hard rethinking about going with your project using the Arduino approach - or live with an I/O rate slower than 1 ms.

to add to @roboteer’s point. FastSyncRead and the other related Fast functions are the quickest way to address a DYNAMIXEL, however, they are not supported by the DYNAMIXEL2Arduino library.

I tried fastBulkRead and the sampling rate is actually even higher than before. Are you sure that FastSyncRead and similar functions are not supported by the DYNAMIXEL2Arduino library?
There are even examples of this (seeFig.)
example_fastBulkread

And if it really doesn’t work is there another way to use fastSyncRead etc. with Arduino IDE ?

First of all, I would like to thank you very much for all your suggestions. I have a feeling that it might be difficult to further reduce the sampling time with the Arduino IDE. As an aside, I have also identified another problem and have already pointed it out in a separate forum post (Connection Pixhawk 4 with openManipulator). Perhaps there is a way to address and solve both challenges at the same time. If you also have ideas or approaches to solving the other problem, I would appreciate your suggestions.

There is no need to try OpenRB, it’s even worse