View unanswered posts | View active topics It is currently Thu Jul 31, 2014 10:27 pm






Reply to topic  [ 8 posts ] 
Encoders - Home Position - HELP!!!! 
Author Message
Rookie

Joined: Mon Nov 08, 2010 2:00 pm
Posts: 6
Post Encoders - Home Position - HELP!!!!
hey

im trying to make a home position for a motor. meaning i wanna press a button and i want the motor to turn to an exact location. whenever i press the button again after having moved the motor i want it to go back to that "home position". iv been trying to do this but its not working out. i really need help on this pleaz

heres what i did but it doesnt work like i want it to work

nMotorEncoder[shoulder] = 0;

while(1==1){

if(joy1Btn(4) && nMotorEncoder[shoulder] < 500){
nMotorEncoderTarget[shoulder] = 500;
motor[shoulder] = 5;
}

else if(joy1Btn(4) && nMotorEncoder[shoulder] > 500){
nMotorEncoderTarget[shoulder] = 500;
motor[shoulder] = -5;
}
}


Thu Nov 11, 2010 1:07 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoders - Home Position - HELP!!!!
If I read your code correctly, when you press and hold button 4, the motor will go to encoder position 500 with 5% motor speed. While the motor is going to the target position, you must hold button 4. If you release the button before it reaches the target, it will stop. What you are describing is different from what the code is doing. The following code will do what you want.
Code:
bool currBtn4State;
bool prevBtn4State = false;
bool homePos = true;
int targetPos = 0;

while (true)
{
    currBtn4State = joy1Btn(4);  //get current button 4 state.

    //
    // Detect the transition of pressing button 4 and toggle homePos.
    //
    if (!prevBtn4State && currBtn4State)
    {
        homePos = !homePos;
    }
    prevBtn4State = currBtn4State;

    //
    // Set target position accordingly.
    //
    if (homePos)
    {
        targetPos = 0;
    }
    else
    {
        targetPos = 500;
    }

    //
    // Set the encoder target.
    //
    nMotorEncoderTarget[shoulder] = targetPos;

    if (nMotorEncoder[shoulder] > targetPos)
    {
        //
        // Overshoot, go back.
        //
        motor[shoulder] = -5;
    }
    else if (nMorotEncoder[shoulder] < targetPos)
    {
        //
        // Not there yet, keep going.
        //
        motor[shoulder] = 5;
    }
    else
    {
        //
        // Reached traget.
        //
        motor[shoulder] = 0;
    }
}


Thu Nov 11, 2010 3:19 pm
Profile
Rookie

Joined: Mon Nov 08, 2010 2:00 pm
Posts: 6
Post Re: Encoders - Home Position - HELP!!!!
Thank you very much. This worked! the only problem is that when it gets to the target position the motor jitters back and forth but ill try and fix it unless u have any solutions. But thank you - this is progress


Thu Nov 11, 2010 4:00 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoders - Home Position - HELP!!!!
Yep, you need to use PID control for that (i.e. the motor speed should be proportional to how far you are away from the target instead of being constant at 5%). You may also want to allow a little tolerance so that it will stop if the error is too small. You need to tune the proportional constant Kp in order to minimize ringing (the motor going back and forth when reaching target). I set the initial Kp value to 0.2 but you need to adjust it up or down so that the motor will smoothly reach the target without going back and forth.
Code:
#define Kp     0.2
#define tolerance 5
int error;
int motorPower;

error = targetPos - nMotorEncoder[shoulder];
if (abs(error) < tolerance)
{
    //
    // Reached target.
    //
    motor[shoulder] = 0;
}
else
{
    //
    // Do PID control here.
    //
    motorPower = (int)(Kp*(float)error);
    if (motorPower > 100)
    {
        motorPower = 100;
    }
    else if (motorPower < -100)
    {
        motorPower = -100;
    }
    motor[shoulder] = motorPower;
}


Last edited by MHTS on Thu Nov 11, 2010 4:50 pm, edited 1 time in total.



Thu Nov 11, 2010 4:28 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoders - Home Position - HELP!!!!
Actually, if you have the PID box checked when defining the "shoulder" motor, RobotC will do PID control for you. So you just need to set nMotorEncoderTarget and don't have to set the motor power at all (I think). I seldom use the RobotC PID control though so you need to play with it and see if it works. In other words, with the PID box checked, the following code might work:
Code:
bool currBtn4State;
bool prevBtn4State = false;
bool homePos = true;
int targetPos = 0;

while (true)
{
    currBtn4State = joy1Btn(4);  //get current button 4 state.

    //
    // Detect the transition of pressing button 4 and toggle homePos.
    //
    if (!prevBtn4State && currBtn4State)
    {
        homePos = !homePos;
    }
    prevBtn4State = currBtn4State;

    //
    // Set target position accordingly.
    //
    if (homePos)
    {
        targetPos = 0;
    }
    else
    {
        targetPos = 500;
    }

    //
    // Set the encoder target.
    //
    nMotorEncoderTarget[shoulder] = targetPos;
}


Thu Nov 11, 2010 4:37 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoders - Home Position - HELP!!!!
Just read the documentation on built-in PID control. Here is the revised code that uses the built-in PID. The only problem is that the built-in PID control still rings. I can't find where I can change the PID constants. So I would still do my own PID control just because I can tune my own PID constants to minimize ringing.
Code:
#define tolerance     5
#define motorpower  50

task main()
{
    bool currBtnState;
    bool prevBtnState = false;
    bool homePos = true;
    int targetPos = 0;

    nMotorEncoder[shoulder] = 0;
    while (true)
    {
        currBtnState = joy1Btn(4);  //get current button state.

        //
        // Detect the transition of pressing button and toggle homePos.
        //
        if (!prevBtnState && currBtnState)
        {
            homePos = !homePos;
        }
        prevBtnState = currBtnState;

        //
        // Set target position accordingly.
        //
        if (homePos)
        {
            targetPos = 0;
        }
        else
        {
            targetPos = 500;
        }

        //
        // Set the encoder target and turn on the motor in the right direction starting at given power.
        //
        nMotorEncoderTarget[shoulder] = targetPos;
        motor[shoulder] = (nMotorEncoder[shoulder] < targetPos)? motorpower:
                                 (nMotorEncoder[shoulder] > targetPos)? -motorpower: 0;

        //
        // Wait for the motor to get there.
        //
        while (abs(targetPos - nMotorEncoder[shoulder]) > tolerance)
        {
        }
      
        //
        // Reached target, stop.
        //
        motor[shoulder] = 0;
    }
}


Fri Nov 12, 2010 2:42 am
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoders - Home Position - HELP!!!!
If you implement your own PID, the code would look like this:
Code:
#define Kp          0.005
#define tolerance   2
#define motorpower  50

task main()
{
    bool currBtnState;
    bool prevBtnState = false;
    bool homePos = true;
    int targetPos = 0;
    int error;
    int motorPower;

    nMotorEncoder[shoulder] = 0;
    while (true)
    {
        currBtnState = joy1Btn(4);  //get current button state.

        //
        // Detect the transition of pressing button and toggle homePos.
        //
        if (!prevBtnState && currBtnState)
        {
            homePos = !homePos;
        }
        prevBtnState = currBtnState;

        //
        // Set target position accordingly.
        //
        if (homePos)
        {
            targetPos = 0;
        }
        else
        {
            targetPos = 500;
        }

        error = targetPos - nMotorEncoder[shoulder];
        if (abs(error) <= tolerance)
        {
            //
            // Reached target.
            //
            motor[shoulder] = 0;
        }
        else
        {
            //
            // Do PID control here.
            //
            motorPower = (int)(Kp*(float)error);
            if (motorPower > 100)
            {
                motorPower = 100;
            }
            else if (motorPower < -100)
            {
                motorPower = -100;
            }
            motor[shoulder] = motorPower;
        }
    }
}


Fri Nov 12, 2010 3:13 am
Profile
Rookie

Joined: Mon Nov 08, 2010 2:00 pm
Posts: 6
Post Re: Encoders - Home Position - HELP!!!!
Thank you very much. i will be playing with this in the next few days


Wed Nov 17, 2010 11:50 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 8 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:  
cron



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