This project has moved and is read-only. For the latest updates, please go here.

Command sequence to the same output

Oct 8, 2014 at 9:00 AM
Hi,

Am playing around a little bit with this API to see what it can do and how it works. For a project of mine, I need a motor to turn 90 degrees to one side, and after that, return to it's original position.

To do this, I had this code in mind:
// 90d CCW
await _brick.DirectCommand.StepMotorAtSpeedAsync(OutputPort.C, -30, 90, true);
// 90d CW
await _brick.DirectCommand.StepMotorAtSpeedAsync(OutputPort.C, 30, 90, true);
When I run this, it will only execute the last command, like the first one is overwritten. I get the same when I run them as a BatchCommand:
// 90d CCW
_brick.BatchCommand.StepMotorAtSpeed(OutputPort.C, -30, 30, true);
// 90d CW
_brick.BatchCommand.StepMotorAtSpeed(OutputPort.C, 30, 30, true);
// Send the commands
await _brick.BatchCommand.SendCommandAsync();
It looks like the second command overwrites the first one on the EV3 itselve.
I also tried the alternative command supplied in the fork of ahilevich (ev3usb):
// 90d CCW
_brick.DirectCommand.StepMotorAtPowerAsync(OutputPort.A, -30, 0, 90, 0, true).Wait();
// Wait for the command to complete
_brick.DirectCommand.WaitOutputReadyAsync(OutputPort.A).Wait();
// 90d CW
_brick.DirectCommand.StepMotorAtPowerAsync(OutputPort.A, 30, 0, 90, 0, true).Wait();
// Wait for the command to complete
_brick.DirectCommand.WaitOutputReadyAsync(OutputPort.A).Wait();
Now, this approach works much better. 5 out of 10 times, it will actually run both commands. The other 5 times, it will just run one of them (CCW or CW).


After reading a bit more about this, I tried a different approach. On start, I would reset all values on the brick (so the value of the motor is 0). Then I would listen to the BrickChanged event.
When the event says that the motor is rotated 0 degrees, I would turn it 90d CW.
When the event says that the motor is rotated 90 degrees, I would turn it 90d CCW.

This works even better while using the WaitOutputReadyAsync command. Now i am getting a 90% success ratio. It will go back and forth for a couple of times, but then, out of the blue, it will just 'skip' a command. In my console application I can see the event is triggered and that the correct command is executed, but the motor will just sit idle. I have to turn it manually by a couple of degrees to 'activate' the event and then it will run again.


Does anyone have any ideas on how this problem can be solved, or even better, why this is happening?

Thanx!
Oct 14, 2014 at 2:18 PM
Hi Eluminate.

You can try to disable internal thread which is getting sensors data. I found that it might have synchronization problems which leads to accidental loss of commands. To disable the thread pass TimeSpan.Zero to ConnectAsync(TimeSpan pollingTime) method.
Oct 27, 2014 at 3:42 PM
Direct Commands are sent immediately. The brick does not wait for the command to complete before accepting another command. So, in the DirectCommand case, your commands are all sent sequentially, very quickly, and overwriting each other.

Batch Commands are batched and sent immediately, but again, those commands don't wait for the previous command to complete before executing the next.

Please see this discussion on how to wait for commands to finish before continuing:

https://legoev3.codeplex.com/discussions/471549