View unanswered posts | View active topics It is currently Wed Oct 22, 2014 7:09 pm






Reply to topic  [ 6 posts ] 
Encoder Programming Question 
Author Message
Rookie

Joined: Thu Nov 11, 2010 1:35 am
Posts: 3
Post Encoder Programming Question
Hello,

I am a rookie this year, and trying to work on programming encoders.

So, my question is, if you set the encoder value at 0 in a specific location at the beginning of autonomous, and then move on to tele-op, does the encoder retain the value for 0, or do I have to reset it. If I have to reset it, how would I go about doing so? :?

Thanks in advance for your help!


Thu Nov 11, 2010 1:42 am
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoder Programming Question
Whenever your motors move, the encoders will register some values. So at the end of autonomous, they won't be zero any more. If you need them to be zero, you need to reset them again. To reset the encoders to zero, it is the same way as you set them to zero the first time (e.g. nMotorEncoder[motorA] = 0).


Thu Nov 11, 2010 6:01 am
Profile
Rookie

Joined: Thu Nov 11, 2010 1:35 am
Posts: 3
Post Re: Encoder Programming Question
Can the encoders used to set the motors to a specific position, similar to servos (but with more range of motion)? This is what we're hoping to use them for. If this is completely outlandish, please let me know!

If so, if we set a zero position at the beginning of autonomous to position the motors from, can we then use the same zero position to program from without resetting it, or do we have to return to the same position and reset it at zero?

Thanks for your help!


Thu Nov 11, 2010 7:41 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoder Programming Question
Yes, motors that have encoders can be used as servos with some programming. And yes you can keep the encoders going without resetting them. Depending on what you use them for. It may be acceptable not resetting them. However, in some scenarios, you may want to reset them. For example, if you use them in a situation where the gear could slip. In time, you may have a cumulative error (i.e. your "home position" is no longer home). Again depending on the situation, you could have it self calibrated (e.g. have a touch sensor at the home position so occassionally, your program will pull the motor back to "home position" until the touch sensor fires, then you can reset the encoder because that's your home position) etc...


Thu Nov 11, 2010 7:51 pm
Profile
Rookie

Joined: Thu Nov 11, 2010 1:35 am
Posts: 3
Post Re: Encoder Programming Question
Thanks, that was helpful! I just started actually trying to program the encoders today, and I've run across a problem.

Here is my tele-op code. I was able to get the arm to move to the encoder position if I press either the right or bottom of the d-pad (tophat values 2 and 4). However, as soon as the arm moves to one of the values, every other command on the joystick stops working. For example, one of the first things I do is press the bottom of the d-pad. The arm moves, but after this nothing will respond on our robot. Did I leave out something very important?

A second question also: I know that I did part of the code wrong (the middle encoder value). I want the arm to move to the middle position from either of the other positions, but by using the shortest distance. Here's an example of what I want: I am in the bottom position (farthest from zero). I want the arm to move to the middle position. However, I want it to move backwards, so it does not have to go around almost a whole rotation. I would like to have the arm able to figure out which way (forwards or backwards) to move the motor the shortest distance. Is there a way to do this easily? I was thinking that maybe there was a way to measure the encoder values, and depending on this choose which way to move, but I did not see any way to do this.

Sorry my code is so long--I wanted to make sure I wasn't leaving anything important out!

If you can help with this, that would be great! (Let me know if I need to clarify anything)

Thank you. :D

Code:
#pragma config(Hubs,  S1, HTMotor,  HTMotor,  HTServo,  none)
#pragma config(Sensor, S2,     Left_Touch_Sensor,   sensorTouch)
#pragma config(Sensor, S3,     Right_Touch_Sensor,  sensorTouch)
#pragma config(Motor,  mtr_S1_C1_1,     Right_Motors,  tmotorNormal, openLoop)
#pragma config(Motor,  mtr_S1_C1_2,     Left_Motors,   tmotorNormal, openLoop, reversed)
#pragma config(Motor,  mtr_S1_C2_1,     Grabber_Arm_Hinge, tmotorNormal, openLoop, encoder)
#pragma config(Motor,  mtr_S1_C2_2,     Grabber_Arm_Height, tmotorNormal, openLoop, encoder)
#pragma config(Servo,  srvo_S1_C3_1,    Windmill_Servo,       tServoContinuousRotation)
#pragma config(Servo,  srvo_S1_C3_2,    Claw_Servo,           tServoStandard)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#include "JoystickDriver.c"


void initializeRobot()
{
  servo[Claw_Servo] = 255;
  servo[Windmill_Servo] = 127;
  nMotorEncoder[Grabber_Arm_Height] = 0;
  nMotorEncoder[Grabber_Arm_Hinge] = 0;
}

task main()
{
  int Left_Motor_Power, Right_Motor_Power;
  Left_Motor_Power = 0;
  Right_Motor_Power = 0;

  initializeRobot();                                   //Initialize the robot

  waitForStart();                             //Wait for the start of the Tele-op phase



  while (true)                                         //While true = always
  {
   getJoystickSettings(joystick);                      //check the joystick settings

    Left_Motor_Power = joystick.joy1_y1 / 2;
    Right_Motor_Power = joystick.joy1_y2 / 2;


    if (abs(Left_Motor_Power) < 10)                     //If the value of the joysticks does not read more than 10, the motors will
    {                                                   //not run. This helps us to save from grinding the motors and creeping.
      Left_Motor_Power = 0;
    }


    if (abs(Right_Motor_Power) < 10)
    {
      Right_Motor_Power = 0;
    }

    if (abs(Left_Motor_Power) > 75)                     //If the value of the joysticks reads over 75, the motors will not run at
    {                                                   //top speed. They will only run at 75 speed at most.
      Left_Motor_Power = (Left_Motor_Power * 100) / 75;
    }

    if (abs(Right_Motor_Power) > 75)
    {
     Right_Motor_Power = (Right_Motor_Power * 100) / 75;
    }

    motor[Right_Motors] = Right_Motor_Power;
    motor[Left_Motors] = Left_Motor_Power;



    if (joy2Btn(1))                                  //Button 1 (Joystick 2) will run the windmill servo backwards
        servo[Windmill_Servo] = 200;                 //to use in case of a jam


    if (joy2Btn(6))                                 //Trigger 5 on Joystick 2 will run the Windmill Servo (a continuous
        servo[Windmill_Servo] = 55;                 //rotation servo) at full speed forward


    if (joy2Btn(8))                                  //Trigger 8 on Joystick 2 will turn off the Windmill servo
        servo[Windmill_Servo] = 127;

    if (joy2Btn(5))                                  //Button 5 on Joystick 2 will close the claw
      servo[Claw_Servo] = 110;                       //Value 110 = servo claw closed


    if(joy2Btn(7))                                   //Button 7 on Joystick 2 will open the claw
      servo[Claw_Servo] = 255;                       //Value 255 = servo claw open

     
    if(joystick.joy2_TopHat == 0)                  //Top d-pad btn (joystick 2) sets the grabber arm height to the default position
    {
      nMotorEncoderTarget[Grabber_Arm_Height] = 1;
      motor[Grabber_Arm_Height] = -8;
      while(nMotorRunState[Grabber_Arm_Height] != runStateIdle) {}    // Wait until encoder value is reached.
    }


    if(joystick.joy2_TopHat == 2)                       //Right d-pad btn (joystick 2) sets the grabber arm height to score position
    {
      nMotorEncoderTarget[Grabber_Arm_Height] = 200;    //CHECK AND ADD THE CORRECT ENCODER VALUE!!!!!
      motor[Grabber_Arm_Height] = 8 | -8;
      while(nMotorRunState[Grabber_Arm_Height] != runStateIdle) {}    // Wait until encoder value is reached.
    }


    if(joystick.joy2_TopHat == 4)                  //Right d-pad btn (joystick 2) sets the grabber arm height to pick-up position
     {
      nMotorEncoderTarget[Grabber_Arm_Height] = 500;   //CHECK AND ADD THE CORRECT ENCODER VALUE!!!!!
      motor[Grabber_Arm_Height] = 8;
      while(nMotorRunState[Grabber_Arm_Height] != runStateIdle) {}   // Wait until encoder value is reached
     }

    wait1Msec(50);
}
}


Sat Nov 13, 2010 5:50 pm
Profile
Guru
User avatar

Joined: Sun Nov 15, 2009 5:46 am
Posts: 1347
Post Re: Encoder Programming Question
I spotted multiple problems with your code. First, I don't understand what the following code was tring to do:
Code:
    if (abs(Left_Motor_Power) > 75)                     //If the value of the joysticks reads over 75, the motors will not run at
    {                                                   //top speed. They will only run at 75 speed at most.
      Left_Motor_Power = (Left_Motor_Power * 100) / 75;
    }

    if (abs(Right_Motor_Power) > 75)
    {
     Right_Motor_Power = (Right_Motor_Power * 100) / 75;
    }

Your comment said you are trying to limit the motor power to 75 but in reality you are multiplying it with 4/3 (1.33) if it is greater than 75. Also note that joystick value has a range of -128 to 127 and the motor range is -100 to 100. So you need to scale the joystick range to the motor range proportionately. I define and use the following macros to take care of the scaling and limiting different values.
Code:
/**
 *  The BOUND macro limits the value (n) within the bounds between the given
 *  low (l) and high (h).
 */
#define BOUND(n,l,h)            (((n) < (l))? (l): ((n) > (h))? (h): (n))

/**
 *  The NORMALIZE macro transforms a value (n) in the range between (sl) and
 *  (sh) to the range between (tl) and (th).
 */
#define NORMALIZE(n,sl,sh,tl,th) (int)(((long)(n) - (sl))*((th) - (tl))/((sh) - (sl)) + (tl))

//
// Joystick input macros.
//
#ifndef DEADBAND_INPUT_THRESHOLD
    #define DEADBAND_INPUT_THRESHOLD 20
#endif

/**
 *  These macros ignore input value (n) that is within the DEADBAND_THRESHOLD.
 *  This is necessary because analog joysticks do not always centered at zero.
 *  So if the joystick is at the rest position, we will consider it zero even
 *  though the value is non-zero but within DEADBAND_THRESHOLD.
 */
#define DEADBAND(n,t)           ((abs(n) > (t))? (n): 0)
#define DEADBAND_INPUT(n)       DEADBAND(n, DEADBAND_INPUT_THRESHOLD)

/**
 *  This macro limits the input value (n) to the range between -128 and 127.
 *  This is useful when calculations on the input value may bring the result
 *  outside of the valid range. This macro will make sure the result is within
 *  bounds.
 */
#define BOUND_INPUT(n)          BOUND(n, -128, 127)

#define MOTOR_MIN_VALUE         -100
#define MOTOR_MAX_VALUE         100
#define NORMALIZE_DRIVE(x,m,n)  NORMALIZE(x, m, n, MOTOR_MIN_VALUE, MOTOR_MAX_VALUE)

//
// I would do the following with the above macros.
//
left_input = DEADBAND_INPUT(joystick.joy1_y1);
right_input = DEADBAND_INPUT(joystick.joy1_y2);

Left_Motor_Power = NORMALIZE_DRIVE(left_input, -128, 127);
Right_Motor_Power = NORMALIZE_DRIVE(right_input, -128, 127);


Secondly, I would avoid using the following code construct because if the enocder doesn't reach target for some reason, your while loop will not come back. That will explain why nothing else work if it is stuck in this while loop.
Code:
    if(joystick.joy2_TopHat == 0)                  //Top d-pad btn (joystick 2) sets the grabber arm height to the default position
    {
      nMotorEncoderTarget[Grabber_Arm_Height] = 1;
      motor[Grabber_Arm_Height] = -8;
      while(nMotorRunState[Grabber_Arm_Height] != runStateIdle) {}    // Wait until encoder value is reached.
    }

Is there a reason why you want to block other operations until the current movement is done? If there is no reason, you can take out the while loop. You only need this if you want to do an operation that depends on the completion of the previous operation.


Sat Nov 13, 2010 7:28 pm
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.