View unanswered posts | View active topics It is currently Fri Nov 28, 2014 5:45 pm






Reply to topic  [ 6 posts ] 
Making a Tetrix 12v behave like a servo 
Author Message
Rookie

Joined: Wed Mar 02, 2011 1:57 pm
Posts: 2
Post Making a Tetrix 12v behave like a servo
After many bad experiences with servo's our team had decided to use the Tetrix 12V motors with an encoder for the same purpose. Our team is using the combination of the Tetrix motor and the encoder in order to elevate our baton dispensing structure. This requires the baton dispensing structure to be able to be able to move to and maintain a certain position. I have written the following code in order to do this.

Quote:
#pragma config(Hubs, S1, HTMotor, HTMotor, HTMotor, none)
#pragma config(Motor, mtr_S1_C1_1, motorD, tmotorNormal, openLoop)
#pragma config(Motor, mtr_S1_C1_2, motorE, tmotorNormal, openLoop)
#pragma config(Motor, mtr_S1_C2_1, Bucket, tmotorNormal, PIDControl, encoder)
#pragma config(Motor, mtr_S1_C2_2, motorG, tmotorNormal, openLoop)
#pragma config(Motor, mtr_S1_C3_1, motorH, tmotorNormal, openLoop)
#pragma config(Motor, mtr_S1_C3_2, motorI, tmotorNormal, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//

task main ()

{

nMotorEncoder[Bucket] = 0; //Resets Encoder Values

wait1Msec(300); //Wait for the encoders to reset

while (1==1) //Do the Following forever
{

while(nMotorEncoder[Bucket] < 500) //while the Encoder value is at less than 500 counts
{
motor[Bucket] = 60; // Move arm up
}

while(nMotorEncoder[Bucket] > 500) //while the Encoder value is greater than 500 counts
{
motor[Bucket] = -60; // Move arm down
}

motor[Bucket] = 0; // Stop Motor Movement

}



}


I wrote this code so that the encoder would reset, the motor would move to 500 encoder counts, then if the motor move down due to gravity or up due to any other reason the motor would move back to 500 encoder counts. When I execute this program the robot does not do this. The motor appears to move extremely rapidly from 200 encoder counts to 500 encoder counts and back without ending.

I would appreciate any advice you could offer.

Thank you in advance.


Wed Mar 02, 2011 2:57 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Making a Tetrix 12v behave like a servo
First off, you probably want to use PID control or you will have ringing (oscillation, i.e. the arm moving back and forth around your target position).
Something like this:
Code:
task main ()
{
    int tolerance = 2;
    nMotorEncoder[Bucket] = 0; //Resets Encoder Values
    wait1Msec(300); //Wait for the encoders to reset
    nMotorEncoderTarget[Bucket] = 500;
    motor[Bucket] = 60;
    while (abs(500 - nMotorEncoder[Bucket]) > tolerance)
    {
        EndTimeSlice();
    }
    motor[Bucket] = 0;
}

This code will drive your bucket motor to its target 500 within a tolerance of 2. Then it will stop. If you want to hold the position, you may not want to stop the motor.


Wed Mar 02, 2011 6:28 pm
Profile
Rookie

Joined: Wed Feb 24, 2010 11:43 pm
Posts: 34
Post Re: Making a Tetrix 12v behave like a servo
Actually MHTS, he is using PID. It's in the #pragma at the top for that motor

The way I see it, he's doing several different things in sequence, rather than examining any/all of them at once.

Code:
while (1==1) //Do the Following forever
{
    // -------- First move it up ---------
    while(nMotorEncoder[Bucket] < 500) //while the Encoder value is at less than 500 counts
      motor[Bucket] = 60; // Move arm up

    // -------- Then move it down -------
    while(nMotorEncoder[Bucket] > 500) //while the Encoder value is greater than 500 counts
      motor[Bucket] = -60; // Move arm down

    // -------- Then stop it -------------
    motor[Bucket] = 0; // Stop Motor Movement

   // Then do it all over again (move it up again. unless it happens to be exactly at 500)

}


It seems like a better choice would be (in simplest form)

Code:
while (true)

    if (nMotorEncoder[Bucket] < 495)
    {
      motor[Bucket] = 60;
    }
    else if (nMotorEncoder[Bucket] > 505)
    {
      motor[Bucket] = -60;
    }
    else
    {
      motor[Bucket] = 0;
    }
    wait1MSec(1);
}


And no that doesn't handle the motor deceleration or anything else (60 seems really fast to try and stop anywhere within range).
but the concept perhaps is more handle-able (new word)


Wed Mar 02, 2011 6:48 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Making a Tetrix 12v behave like a servo
I am not familiar with the built-in PID in RobotC but in theory PID should regulate the power to the motor so that it will slow down when approaching the target. I am always assuming built-in PID is not engaged until you use nMotorEncoderTarget (must set a setpoint to start PID). But the code posted sets the motor power to either 60 or -60. Unless built-in PID is ignoring the value 60 you set, going between 60 and -60 will certainly cause ringing. PID is supposed to regulate the power level as well as the motor direction according to the difference between the current encoder value and the target encoder value. So you shouldn't have to test the encoder value yourself and set the power and direction. But I could be wrong. We don't use the built-in PID, we have our own PID library. My knowledge of built-in PID is from reading other threads in the forum and that's how other people use built-in PID. :)


Wed Mar 02, 2011 6:56 pm
Profile
Rookie

Joined: Wed Feb 24, 2010 11:43 pm
Posts: 34
Post Re: Making a Tetrix 12v behave like a servo
MHTS wrote:
I am not familiar with the built-in PID in RobotC but in theory PID should regulate the power to the motor so that it will slow down when approaching the target. I am always assuming built-in PID is not engaged until you use nMotorEncoderTarget (must set a setpoint to start PID). But the code posted sets the motor power to either 60 or -60. Unless built-in PID is ignoring the value 60 you set, going between 60 and -60 will certainly cause ringing. PID is supposed to regulate the power level as well as the motor direction according to the difference between the current encoder value and the target encoder value. So you shouldn't have to test the encoder value yourself and set the power and direction. But I could be wrong. We don't use the built-in PID, we have our own PID library. My knowledge of built-in PID is from reading other threads in the forum and that's how other people use built-in PID. :)


He's using the built in PID for speed control, not for positioning. And you're right, what he's doing will certainly cause ringing. And you're also right that he probably should be using a PID (or at least a PI) algorithm to accurately position the arm. However, in most cases, people don't need to position the arm to the exact value and a simple on/off controller with a dead band is the simplest to get working for a new programmer.

If I was to give another hint to technowiz101 it would be to look at the nMotorEncoderTarget[] functionality. This, in essence, seems to change the PID to a positioning algorithm. But even that has bugs in the implementation for Tetrix motors that are frustrating when not understood (see viewtopic.php?f=52&t=2906).


Thu Mar 03, 2011 9:22 am
Profile
Rookie

Joined: Sun Dec 05, 2010 11:58 am
Posts: 28
Post Re: Making a Tetrix 12v behave like a servo
I believe a speed-based PID is activated if you do not use nMotorEncoderTarget.


Fri Mar 04, 2011 8:16 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 6 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.