you're reading...
leJOS Features

Motor synchronization problems – part 2

As explained in Part 1 of this post, motor synchronization of motor operations in leJOS depends primarily on starting these operations at the same time. Once started the underlying mechanism will ensure that the motors remain in sync. Unfortunately the existing motor API has no mechanism to express this relationship. So we need a way to indicate to the system that move operations (this also includes changing the speed of an already running motor) for two or more motors should happen at the same time. We then need to work out how to actually implement this. In designing this new API there were a number of other considerations, or requirements:

  • It should be easy to convert existing code to take advantage of the new API.
  • The new API should be able to function with local or remote motors (though it is probably acceptable to require that all of the motors that are synchronized are attached to the same brick).
  • It should be possible to synchronize the return of motor move information (like getTachoCount) as well as actual motor move rotate requests.
  • Some parts of the API are likely to be called frequently so if possible these methods should avoid generating garbage (as causing the GC to be invoked often may cause problems for other real time tasks).

After some discussion an experimental interface that is based upon extending the current RegulatedMotor interface has been chosen. This allows the use of the existing mechanism of using separate calls to set things like target velocity, acceleration etc, while still meeting the above requirements. The basic approach is to use a “lead” or master motor to hold the list of motors to synchronize with, and to bracket calls to the existing API with synchronization markers.  So for example suppose we have code that rotates two motors by 360 degrees:

RegulatedMotor mA = new EV3LargeRegulatedMotor(BrickFinder.getDefault().getPort("A"));
RegulatedMotor mD = new EV3LargeRegulatedMotor(BrickFinder.getDefault().getPort("D"));

mA.rotate(360, true);
mD.rotate(360, true);

The above code says nothing about synchronization. Using the new API we would have:

RegulatedMotor mA = new EV3LargeRegulatedMotor(BrickFinder.getDefault().getPort("A"));
RegulatedMotor mD = new EV3LargeRegulatedMotor(BrickFinder.getDefault().getPort("D"));
mA.synchronizeWith(new RegulatedMotor[] {mD});

mA.rotate(360, true);
mD.rotate(360, true);

The above indicates that we wish to synchronize some operations between motors A and D, and the start/end calls bracket the operations that should be synchronized. Operations outside of these brackets function just as before.

The underlying operation is relatively simple. When the call to startSynchronization is made the current state of all motors that are to be synchronized is obtained. This in effect freezes the results that calls to getTachoCount etc. will return. This frozen state can then be modified by making calls to setSpeed etc or rotateTo etc. However none of these operations is actually executed until the final endSynchronization call is made At this point all of the accumulated state is passed into the kernel module to allow all of the motor operations to start at the same time.

So what happens if there are multiple rotate calls for the same motor within a single set of start/end brackets. To understand this we need to be aware of a further rule. Only non blocking calls can be used between start/end. With this rule things become easier to understand. If multiple calls are made to rotate then in effect only the last call will actually have any effect, this is pretty much what would happen if you performed the same thing without synchronization and followed one non blocking rotate by another. There are lots of possible special cases, but if you keep things simple things should work as you would expect.

The end result of this can be seen in the following image:


This is an updated version of the image from part 1, showing the position of the robot after 32 (16 in the case of leJOS 0.8.1) move operations. Red is the starting position, blue leJOS on the NXT, Yellow is leJOS EV3 0.8.1 and pink is the Lego firmware. In this image green is the result from leJOS EV3 using the new synchronization primitives. As can be seen this is a considerable improvement .

With the addition of the synchronization mechanism movements on the EV3 can be as good as if not better than that obtained on the NXT. However we are not finished yet. Take another look at the image, do you see how all of the results show movement backwards from the starting position? What is causing this? I hope to investigate this further in the next post.


5 thoughts on “Motor synchronization problems – part 2

  1. Are the new motor synchronization APIs available or will they be part of a new leJOS release? I have seen this problem using the standard EV3 software and was hoping to use java to alleviate the problem.

    Posted by Joe | 2014/10/30, 15:58
  2. The new API is currently part of the leJOS git master. It has not yet been made available as part of an official release. It will be released at some point in the future.

    Posted by gloomyandy | 2014/10/30, 16:05
  3. Hi ! The methods startSynchronization(); and endSynchronization(); are enable in RMI ?

    Posted by Edgar Fajardo | 2016/04/06, 05:04

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

About leJOS News

leJOS News keeps you up-to-date with leJOS. It features latest news, explains cool features, shows advanced techniques and highlights amazing projects. Be sure to subscribe to leJOS News and never miss an article again. Best of all, subscription is free!
Follow leJOS News on WordPress.com
%d bloggers like this: