To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.nxtOpen lugnet.robotics.nxt in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / NXT / 495
494  |  496
Subject: 
Re: Two motors at the same time... It is possible?
Newsgroups: 
lugnet.robotics.nxt
Date: 
Mon, 19 Feb 2007 01:47:37 GMT
Viewed: 
14457 times
  
In lugnet.robotics.nxt, Patrick J. Levy wrote:
I was wondering if is possible to run two motors at the same time, using
diferente parameters (speed and degrees)...

It is possible.  The NXC API doesn't currently wrap this capability in a really
simple function.

The code bellow works, but first the motor A runs, then the motor B runs.

----------------------------
task main(){
     RotateMotor(OUT_A, 50, 360);
     RotateMotor(OUT_B, 100, 180);
}


The RotateMotor API function calls a subroutine written in NBC that does not
return until the tachometer limit target has been reached.  That's why the code
above acts as you describe (i.e., motor a running followed by motor b running).

There is not a kind of multitasking? This code bellow does not even works
(only the motor A runs).:

----------------------------
task MotorA(){
     RotateMotor(OUT_A, 50, 360);
}

task MotorB(){
     RotateMotor(OUT_B, 100, 180);
}

task main(){
     start MotorA;
     start MotorB;
}

In this case you have two threads running concurrently which both call into the
same subroutine.  That's a recipe for disaster.  Exactly what will happen when
two threads simultaneously call the same subroutine is undefined.

The reason that RotateMotor is implemented behind the scenes as a subroutine is
because in order to do tacho-based motor rotation you need to do something like
the following procedure:

a) start a motor rotating with a new tachometer limit.
b) loop while checking the status of the motor until it is no longer running
c) stop the motor using speed synchronization for a speed of zero.

You can use a more complicated algorithm that more closely models the exact
behavior of the NXT-G Move block if you desire.  But the RotateMotor subroutine
basically does the three steps you see above.

If you want to do these three things for two different motors simultaneously you
can, but at the moment you have to roll your own code to do the job.

#include "NXCDefs.h"

task motorA()
{
  // start motor A rotating with a tacho limit of 360
  SetOutput(OUT_A,
            OutputMode, OUT_MODE_MOTORON+OUT_MODE_BRAKE,
            RegMode, OUT_REGMODE_IDLE,
            TachoLimit, 360,
            RunState, OUT_RUNSTATE_RUNNING,
            Power, 50,
            UpdateFlags, UF_UPDATE_TACHO_LIMIT+UF_UPDATE_SPEED+UF_UPDATE_MODE);
  // loop until runstate is not running
  until(MotorRunState(OUT_A) != OUT_RUNSTATE_RUNNING);
  // regulate for speed = 0
  SetOutput(OUT_A,
            OutputMode, OUT_MODE_MOTORON+OUT_MODE_BRAKE+OUT_MODE_REGULATED,
            RegMode, OUT_REGMODE_SPEED,
            RunState, OUT_RUNSTATE_RUNNING,
            Power, 0,
            UpdateFlags, UF_UPDATE_SPEED+UF_UPDATE_MODE);
  // Verifies that motor doesn't rotate for 50ms, else loops
  int rotCount = MotorRotationCount(OUT_A);
  int oldRotCount = rotCount - 1;
  while (oldRotCount != rotCount) {
    oldRotCount = rotCount;
    Wait(50);
    rotCount = MotorRotationCount(OUT_A);
  }
  SetOutput(OUT_A,
            OutputMode, OUT_MODE_COAST,
            RunState, OUT_RUNSTATE_IDLE,
            UpdateFlags, UF_UPDATE_MODE);
}

task motorB()
{
  // start motor B rotating with a tacho limit of 180
  SetOutput(OUT_B,
            OutputMode, OUT_MODE_MOTORON+OUT_MODE_BRAKE,
            RegMode, OUT_REGMODE_IDLE,
            TachoLimit, 180,
            RunState, OUT_RUNSTATE_RUNNING,
            Power, 100,
            UpdateFlags, UF_UPDATE_TACHO_LIMIT+UF_UPDATE_SPEED+UF_UPDATE_MODE);
  // loop until runstate is not running
  until(MotorRunState(OUT_B) != OUT_RUNSTATE_RUNNING);
  // regulate for speed = 0
  SetOutput(OUT_B,
            OutputMode, OUT_MODE_MOTORON+OUT_MODE_BRAKE+OUT_MODE_REGULATED,
            RegMode, OUT_REGMODE_SPEED,
            RunState, OUT_RUNSTATE_RUNNING,
            Power, 0,
            UpdateFlags, UF_UPDATE_SPEED+UF_UPDATE_MODE);
  // Verifies that motor doesn't rotate for 50ms, else loops
  int rotCount = MotorRotationCount(OUT_B);
  int oldRotCount = rotCount - 1;
  while (oldRotCount != rotCount) {
    oldRotCount = rotCount;
    Wait(50);
    rotCount = MotorRotationCount(OUT_B);
  }
  SetOutput(OUT_B,
            OutputMode, OUT_MODE_COAST,
            RunState, OUT_RUNSTATE_IDLE,
            UpdateFlags, UF_UPDATE_MODE);
}

task main()
{
  Precedes(motorA, motorB);
}

Hope this helps,

John Hansen



Message has 2 Replies:
  Re: Two motors at the same time... It is possible?
 
John, (...) It worked just as I expected. The two motors now are rotating the same time. Thanks to your example, now I am giving some time to understand this setOutput call, and reading all the documentation (it is quite easier with pratical (...) (18 years ago, 19-Feb-07, to lugnet.robotics.nxt)
  Re: Two motors at the same time... It is possible?
 
The code is working right well! But i think the stall control at the end o each task has no meaning there, since the until loop does not let the script reach it if the motor become staled. (...) Patrick (18 years ago, 19-Feb-07, to lugnet.robotics.nxt)

Message is in Reply To:
  Two motors at the same time... It is possible?
 
Hi people, I was wondering if is possible to run two motors at the same time, using diferente parameters (speed and degrees)... The code bellow works, but first the motor A runs, then the motor B runs. ---...--- task main(){ RotateMotor(OUT_A, 50, (...) (18 years ago, 18-Feb-07, to lugnet.robotics.nxt)

6 Messages in This Thread:


Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR