TetrixRegulatedMotor jitters at target position

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

TetrixRegulatedMotor jitters at target position

Postby wireless_roth » Sat Mar 30, 2013 5:45 pm

Hello,

I use two TetrixRegulatedMotor inside a DifferentialPilot.
Whenever the motors reach their target movement (e.g. when a travel() call reached the destination), the motors "jitter" for some seconds.
This means: they move back and forth some degrees, 10 to 20 times, causing a deep humming. I assume the motors want to precisely move the a certain angle, but always overshoot the angle, thus want to compensate and turn back.

Even though, it may be the intention of a regulated motor to precisely turn to a required angle, this behaviour does not seem to be reasonalbe inside a pilot class. E.g. to move the robot 50cm takes the robot 2 seconds, but it takes 20 seconds more jittering without doing useful things. Also rotate(), arc() etc. 90% of the time is used by the jittering effect, not by the actual movement.

If I used forward() and the flt() when the destination is reached, the robot behave as expected, but then I had to check the tacho count on myself. To always use flt() to stop the motors inside a pilot means, to reimplement huge parts of the DifferentialPilot class, as the stopping mechanism is part of the Pilot class.

Any suggestions?

Regards

Jörg
User avatar
wireless_roth
Novice
 
Posts: 41
Joined: Sat Jun 30, 2007 1:30 pm

Re: TetrixRegulatedMotor jitters at target position

Postby kirkpthompson » Sat Mar 30, 2013 7:29 pm

Hi.

The lejos.nxt.addon.tetrix.TetrixRegulatedMotor class has never been tested [by me] with the DifferentialPilot. I do know:
    That an encoder is required to use the TetrixRegulatedMotor class. Do you have one installed?
    The Tetrix motor controller does exhibit this behavior when positioning to a specific angle.
The Tetrix motor controller itself manages the movements withing it's own firmware so maybe they don't work well with the pilots. Your testing and feedback is valuable for characterizing the behavior so please post any new findings you may come across in your explorations.

Best,
-K
Leg Godt!
User avatar
kirkpthompson
leJOS Team Member
 
Posts: 304
Joined: Wed Dec 05, 2007 1:27 am
Location: New Mexico, USA

Re: TetrixRegulatedMotor jitters at target position

Postby wireless_roth » Sun Mar 31, 2013 2:03 pm

Hi,

yes, I use encoders.

I browsed through the relevant classes (btw. I was very impressed by the code).
The mode "run to position" (MODEBIT_SEL_POSITION) in TetrixMotorController (also called "servo-like mode" in some documentation) does not seem to be appropriate for driving a robot. For driving, the developer mainly is interested in controlling the motor speeds (e.g. to exactly drive straight) and not to exactly reach a certain motor angle. Of course, a certain position should be reached, but it is not required that the motor angle is exactly x degrees, especially when using gears.

For a heavy robot, the inertia causes always overshooting the target angle, thus the motor controller ends up infinitely moving back and forth, even though the end position more or less is reached. Note that this problem is not related to DifferentialPilot, also if the motion control directly uses the TetrixRegulatedMotor, this problem exists (but only for rotate(), not forward(), backward())

As you said, the mode is executed inside the controller firmware, thus not changeable. My approach would be to create a variation of TetrixRegulatedMotor. The idea is to simulate the rotate method by forward/stop, where a background thread supervises the tacho value. When the tacho value is about to reach the desired value, it perfoms a stop. As stop does not execute the "servo-like mode", toggling back and forth is avoided.

Another approach would be to use a modified protocol to the motor controller. I'm not familiar with this controller, but maybe there is a way to prohibit endlessly moving back and forth (e.g. different commands/modes, or a thread could check, whether the controller is "toggling" the motors and after some tries, the command is stopped).

I can try to start some experiments in the next days. However, comments or suggestions are welcome.

I would be interested, if there are other people who program Tetrix robots with lejos. If yes, how do they control their DC motors?

Regards

Jörg
User avatar
wireless_roth
Novice
 
Posts: 41
Joined: Sat Jun 30, 2007 1:30 pm

Re: TetrixRegulatedMotor jitters at target position

Postby wireless_roth » Mon Apr 01, 2013 3:10 pm

Hello,

I developed an own tetrix motor class that avoids the mentioned problem. It runs more or less as describe in my earlier post. Some remarks:

- As the TetrixRegulatedMotor is instantiated by factory method from the TetrixMotorController, I could not simply subclass TetrixRegulatedMotor. Instead, my class wrappes most of the TetrixRegulatedMotor methods and simply passes calls to the original instance. I know - this is not an ideal approach, but I did not want to change any lejos class.

- TetrixRegulatedMotor does not seem to properly indicate movement with the method isMoving(). Thus, I manage an own flag. However, this flag does not detect real movement asking the controller, but only indicates the status inside the program. This might not be the same, for now, it is adaquate.

- As intended for robot driving, rotate(angle) now only approximates a target angle and does not perform a back-and-forth-search. It requires some heuristics to stop nearly the desired tacho count. I implemented two approaches: the motor slows down before the target is reached, this makes it easier for the monitor thread to execute the stop command at the right time. Second: the target angle is reduced by a fix constant. In my experiments, the error was +-20 degrees. All parameters are result of some experiments and may not be adaquate for all mechanics and power settings.

- I successfully tested instances of my TetrixRegulatedDriveMotor inside the DifferentialPilot. Good news: it works as expected.

Regards


Jörg




Code: Select all
package jr.motion;


import lejos.util.Delay;
import lejos.robotics.RegulatedMotor;
import lejos.robotics.RegulatedMotorListener;
import lejos.nxt.addon.tetrix.TetrixRegulatedMotor;


public class TetrixRegulatedDriveMotor implements RegulatedMotor {


    private final static int TIME_TO_SLOW_DOWN=1200;  // ms before the target is reached the motor slows down in order to easier stop at the required tacho count
    private final static int MIN_SLOW_DOWN_SPEED=120; // minimal speed (degree/s) when slowing down near the target
    private final static int MIN_ROTATE_DEGREES=15;   // rotate cannot rotate very small angles; below this angle, rotate will not perform any movement
    private final static int MIN_CYCLE_TIME=20;       // Thread cycle time to monitor the tach count

    private TetrixRegulatedMotor regulatedMotor;      // The actual motor

    private boolean privateIsMoving=false;            // Own flag to detect movement, as isMoving inside TetrixRegulatedMotor does not indicate movement properly


    public TetrixRegulatedDriveMotor(TetrixRegulatedMotor regulatedMotor) {
        this.regulatedMotor=regulatedMotor;
    }


    public void addListener(RegulatedMotorListener listener) {
        regulatedMotor.addListener(listener);
    }

    public RegulatedMotorListener removeListener() {
        return regulatedMotor.removeListener();
    }


    public void rotate(int angle) {
        rotate(angle, false);
    }

    public void rotate(final int degrees, final boolean immediateReturn) {
        if (Math.abs(degrees)<MIN_ROTATE_DEGREES)
            return;

        Thread rotateThead=new Thread(new Runnable() {
             public void run() {
                 int sgn=1;
                 int absDegrees=degrees;

                 int startTacho=getTachoCount();
                 int orgSpeed=getSpeed();
                 int effectiveMinSlowDownSpeed=Math.min(MIN_SLOW_DOWN_SPEED,orgSpeed);

                 if (degrees<0) {
                     backward();
                     sgn=-1;
                     absDegrees=-degrees;
                 }
                 else
                     forward();

                 absDegrees-=MIN_ROTATE_DEGREES;

                 while (true) {
                     int remainingDegrees=absDegrees-(getTachoCount()-startTacho)*sgn;
                     if (remainingDegrees<=0) {
                         stop(immediateReturn);
                         setSpeed(orgSpeed);
                         return;
                     }
                     int remainingMs=Math.max(remainingDegrees*1000/getSpeed(),2);

                     if (remainingMs<TIME_TO_SLOW_DOWN) {
                         setSpeed(effectiveMinSlowDownSpeed+(orgSpeed-effectiveMinSlowDownSpeed)*remainingMs/TIME_TO_SLOW_DOWN);
                     }

                     Delay.msDelay(Math.min(MIN_CYCLE_TIME,remainingMs));
                 }
             }
          });

       privateIsMoving=true;
       rotateThead.start();

       if (!immediateReturn)
           waitComplete();
    }


    public int getRotationSpeed() {
        return regulatedMotor.getRotationSpeed();
    }

   public void stop() {
        regulatedMotor.stop();
        privateIsMoving=false;
    }

    public void stop(boolean immediateReturn) {
        regulatedMotor.stop(immediateReturn);
        privateIsMoving=false;
    }

    public void flt(boolean immediateReturn) {
        regulatedMotor.flt(immediateReturn);
        privateIsMoving=false;
    }

    public void flt() {
        regulatedMotor.flt();
        privateIsMoving=false;
    }

    public void waitComplete() {
        while (isMoving()) {
            Delay.msDelay(50);
        }
    }

    public void rotateTo(int limitAngle) {
        rotateTo(limitAngle, false);
    }

    public void rotateTo(int limitAngle, boolean immediateReturn) {
        regulatedMotor.rotateTo(limitAngle, immediateReturn);
    }

    public void setSpeed(int speed) {
        regulatedMotor.setSpeed(speed);
    }

    public int getSpeed() {
        return regulatedMotor.getSpeed();
    }

    public float getMaxSpeed() {
        return regulatedMotor.getMaxSpeed();
    }

    public boolean isStalled() {
        return regulatedMotor.isStalled();
    }

    public void setStallThreshold(int error, int time) {
        regulatedMotor.setStallThreshold(error, time);
    }

    public void setAcceleration(int acceleration) {
        regulatedMotor.setAcceleration(acceleration);
    }

    public int getTachoCount() {
        return regulatedMotor.getTachoCount();
    }

    public synchronized void resetTachoCount() {
        regulatedMotor.resetTachoCount();
    }

    public int getLimitAngle() {
        return regulatedMotor.getLimitAngle();
    }

    public void forward() {
        regulatedMotor.forward();
        privateIsMoving=true;
    }

    public void backward() {
        regulatedMotor.backward();
        privateIsMoving=true;
    }

    public boolean isMoving() {
        return regulatedMotor.isMoving() || privateIsMoving;
    }


    public void setReverse(boolean reverse) {
        regulatedMotor.setReverse(reverse);
    }

}

User avatar
wireless_roth
Novice
 
Posts: 41
Joined: Sat Jun 30, 2007 1:30 pm

Re: TetrixRegulatedMotor jitters at target position

Postby wireless_roth » Sun Apr 14, 2013 3:28 pm

Hello,

OK, my solution does not seem to be too interesting...

However, I want to improve the class. Especially when the battery is not fully charged, the speed control gets more and more critical. As a result, the robot fails to drive straight forward. Maybe the pilot class can compensate some controller issues related to the speed or power control.

Does anyone can provide me a link to the DC motor controller specification. I searched for some hours but cannot find an appropriate document.

Regards

Jörg
User avatar
wireless_roth
Novice
 
Posts: 41
Joined: Sat Jun 30, 2007 1:30 pm

Re: TetrixRegulatedMotor jitters at target position

Postby kirkpthompson » Sun Apr 14, 2013 8:56 pm

Hi.

Try http://bit.ly/158CTaA

Best,
-K
Leg Godt!
User avatar
kirkpthompson
leJOS Team Member
 
Posts: 304
Joined: Wed Dec 05, 2007 1:27 am
Location: New Mexico, USA

Re: TetrixRegulatedMotor jitters at target position

Postby eriknau » Tue Jun 11, 2013 10:41 am

Since you are using the TetrixControllerFactory class I'm asking here how to add it to my leJOS environment. I have the basic installation of leJOS NXJ on Mountain Lion, compiling from command line. Do I compile this http://svn.code.sf.net/p/lejos/code/trunk/classes/src/lejos/nxt/addon/tetrix/TetrixControllerFactory.java to a class file with nxjc and put the class in the lib folder of leJOS NXJ installation under /addon/tetrix? This is what I tried but the objects are not recognized when I compile a program using them.
Thanks,
Erik
eriknau
New User
 
Posts: 13
Joined: Mon Jun 10, 2013 7:33 pm

Re: TetrixRegulatedMotor jitters at target position

Postby eriknau » Fri Jun 14, 2013 4:05 am

Never mind my question, I got it on another thread, http://lejos.sourceforge.net/forum/viewtopic.php?f=7&t=4435
eriknau
New User
 
Posts: 13
Joined: Mon Jun 10, 2013 7:33 pm


Return to NXJ Software

Who is online

Users browsing this forum: Google [Bot] and 6 guests

more stuff