View unanswered posts | View active topics It is currently Fri Nov 22, 2019 11:16 am






Reply to topic  [ 7 posts ] 
Issues regarding the vex quadrature encoder 
Author Message
Rookie

Joined: Mon Apr 27, 2015 11:33 am
Posts: 5
Post Issues regarding the vex quadrature encoder
I am using the quadrature encoder to measure the distance my robot drive, so I defined a function to translate the metric distance to encoder counts. I used robotC debugger to see how the encoder sensor ticks change when I pushes the robot, and write down the corresponding encoder ticks to metric distances, and use these tuples to calculate the proportion.

But here comes the issue. I used the calculated proportion to write an autonomous program to drive my robot some distance, say 30 centimeters; the calculated proportion is 10.67, so it is about 320 encoder ticks. But when the program reaches the target encoder tick, the robot will always drive several centimeters more, about 34 cm rather than 30. I also used the debugger to check the sensor value, and when the robot stops, the reported encoder value is around 320, not more than 325, which means the metric distance error should not exceed 1 cm. So where does this error come from?

The more weired issue is when I use the same proportion to drive the robot backward, say -30 cm, which means -320 encoder ticks. In this case, when the program reaches the target encoder tick, the metric distance error will not exceed 1 cm. Why does the quadrature encoder has different performance in the different directions??

My robot's sensor configuration is as follows, the 'base_quad' is the one I am using to measure distance. I plugged two quad encoders and made them one port (port 4) separated on purpose, because when I plug them in port 2, 3 and 4, 5, the first one will only return -1, 1 or 0 values. Is this a bug of robotC or the VEX cortex?

Code:
#pragma config(Sensor, dgtl1,  bumper,         sensorTouch)
#pragma config(Sensor, dgtl2,  base_quad,      sensorQuadEncoder)
#pragma config(Sensor, dgtl5,  lift_quad,      sensorQuadEncoder)
#pragma config(Sensor, dgtl7,  jump7,          sensorDigitalIn)
#pragma config(Sensor, dgtl8,  jump8,          sensorDigitalIn)
#pragma config(Sensor, dgtl9,  arm_pump,       sensorDigitalOut)
#pragma config(Sensor, dgtl10, gripper_pump,   sensorDigitalOut)
#pragma config(Sensor, dgtl11, cube_pump,      sensorDigitalOut)


I have been stuck here for several days, I really appreciate if anyone can answer my questions or point me somewhere I can look for.


Mon Apr 27, 2015 12:00 pm
Profile
Expert

Joined: Thu Dec 01, 2011 12:07 am
Posts: 151
Post Re: Issues regarding the vex quadrature encoder
Please post your entire code. You may have issues with an INTeger variable truncating the decimal and need a FLOATing point variable instead.


Mon Apr 27, 2015 10:30 pm
Profile
Rookie

Joined: Mon Apr 27, 2015 11:33 am
Posts: 5
Post Re: Issues regarding the vex quadrature encoder
CARBOT wrote:
Please post your entire code. You may have issues with an INTeger variable truncating the decimal and need a FLOATing point variable instead.


Thanks for your reply, but could you please explain it a bit more? As far as I know the SensorValue[] returns type 'short', where do I need floating point variable?


Mon Apr 27, 2015 10:47 pm
Profile
Site Admin
Site Admin

Joined: Thu May 24, 2012 12:15 pm
Posts: 722
Post Re: Issues regarding the vex quadrature encoder
On top of what Carbot has said; the issue you may be encountering is commonly caused by the robot "drifting" past its target value. Essentially, when you tell the robot to go from a full-speed movement to a dead stop, the motor may continue to 'drift' past the target point. This drift is a fairly common issue and is affected by several factors, including the weight of the robot, weight distribution, speed of the motors, type of wheels being used, the drivetrain, the surface the robot is being run on, etc.

A good analogy for this is driving a car at 20 mph until the front bumper reaches a stop sign, then slamming on the brakes. Even though you've technically told the car to 'stop' exactly at the stop sign, the car will most likely keep sliding/moving past the target point. The faster you are moving (or the more inerta the car has), the further it will 'drift' past the stop sign.

A good way to test this is to record the encoder values of the same movement with the robot on different surfaces and free spinning with the wheels off the ground.

_________________
Check out our Blog! And our Facebook page!
Need help? Take a look at our updated help documentation and the ROBOTC Forums.


Tue Apr 28, 2015 12:56 pm
Profile
Rookie

Joined: Mon Apr 27, 2015 11:33 am
Posts: 5
Post Re: Issues regarding the vex quadrature encoder
JohnWatson wrote:
On top of what Carbot has said; the issue you may be encountering is commonly caused by the robot "drifting" past its target value. Essentially, when you tell the robot to go from a full-speed movement to a dead stop, the motor may continue to 'drift' past the target point. This drift is a fairly common issue and is affected by several factors, including the weight of the robot, weight distribution, speed of the motors, type of wheels being used, the drivetrain, the surface the robot is being run on, etc.

A good analogy for this is driving a car at 20 mph until the front bumper reaches a stop sign, then slamming on the brakes. Even though you've technically told the car to 'stop' exactly at the stop sign, the car will most likely keep sliding/moving past the target point. The faster you are moving (or the more inerta the car has), the further it will 'drift' past the stop sign.

A good way to test this is to record the encoder values of the same movement with the robot on different surfaces and free spinning with the wheels off the ground.


Thanks for your reply, of course I know the "drifting" issue, but it's not the problem here. In fact, what I was doing was recording the encoder values through two ways: 1) manually push the robot and 2) remote control using joystick. In both ways the encoder would give about 320 ticks for 30 cm distance. But when I use the auto program to drive the robot the same distance (using the measure of 320 ticks for 30 cm), when the robot *completely* stops, the encoder value shows it's around 320 ticks (not more than 10 ticks error), but the actual distance error could be 3 to 4 cm, which is not as expected.

EDIT: A possible reason could be the motor exceeds the maximum rotating speed of quadrature encoder's limit, in which case the robot drives more ticks but the encoder can not record them properly. I measured the time and ticks in the auto program, and the calculated revolutions per second is at most 13-14, could this be the reason? I tried a smaller value for motor speed and the error also reduced.


Wed Apr 29, 2015 2:49 am
Profile
Site Admin
Site Admin

Joined: Thu May 24, 2012 12:15 pm
Posts: 722
Post Re: Issues regarding the vex quadrature encoder
We will need to see the program to debug it; if drifting has been accounted for, then the problem may be with how the program is using/accessing the encoder values, how the motors are being run and stopped, etc. Please post the code using the [code] tags, if possible, and we will be more than happy to take a look at it for you.

_________________
Check out our Blog! And our Facebook page!
Need help? Take a look at our updated help documentation and the ROBOTC Forums.


Wed Apr 29, 2015 4:21 pm
Profile
Rookie

Joined: Mon Apr 27, 2015 11:33 am
Posts: 5
Post Re: Issues regarding the vex quadrature encoder
JohnWatson wrote:
We will need to see the program to debug it; if drifting has been accounted for, then the problem may be with how the program is using/accessing the encoder values, how the motors are being run and stopped, etc. Please post the code using the code tags, if possible, and we will be more than happy to take a look at it for you.


Thanks for your promote reply, as I encountered this problem when I was debugging PID control so the original program is a bit long, I would paste the experimental code below where I can reproduce the error.

Here are the steps to reproduce the error. I put a measure tape beside the robot to measure the metric distance the robot moves, all the values are recorded when the robot was completely stopped. As I mentioned before I used two ways of both manually pushing & joystick controlling to record the encoder values (in the debugger in robotC). The calculated proportion of encoder ticks to metric distance in centimeters is about 10.6, which is 530 ticks for 50 cm. I used the code below to run the robot for multiple times for a certain speed, which is set in variable 's_drive_spd'. I set the speed to 127(full speed of), 80, 50, respectively. And here are the results I got.

Speed = 127:
drive(50) ----> LAST error (-32, -11), actual distance of about 57 cm
drive(-50) ----> LAST error (33, 53), actual distance of about -(57-6) cm

Speed = 80:
drive(50) ----> LAST error (-24, 7), actual distance of about 53 cm
drive(50) ----> LAST error (30, 28), actual distance of about -(53-2) cm

Speed = 50:
drive(50) ----> LAST error (10, 7), actual distance of about 49 cm
drive(50) ----> LAST error (-10, -4), actual distance of about -(49-0) cm

Note: the 'LAST error (left_encoder_stop_err, right_encoder_stop_err)' is an average from three independent runs.

As you can see, when I set the speed a higher value, the more error encoder would produce.

Code:
#pragma config(Sensor, in8,    gyro,           sensorGyro)
#pragma config(Sensor, dgtl1,  base_quad_r,    sensorQuadEncoder)
#pragma config(Sensor, dgtl3,  jump7,          sensorDigitalIn)
#pragma config(Sensor, dgtl4,  jump8,          sensorDigitalIn)
#pragma config(Sensor, dgtl5,  lift_quad,      sensorQuadEncoder)
#pragma config(Sensor, dgtl7,  base_quad_l,    sensorQuadEncoder)
#pragma config(Sensor, dgtl9,  arm_pump,       sensorDigitalOut)
#pragma config(Sensor, dgtl10, gripper_pump,   sensorDigitalOut)
#pragma config(Sensor, dgtl11, cube_pump,      sensorDigitalOut)
#pragma config(Motor,  port1,           frontLeftMotor, tmotorVex393HighSpeed_HBridge, openLoop, driveLeft)
#pragma config(Motor,  port2,           backLeftMotor, tmotorVex393HighSpeed_MC29, openLoop, driveLeft)
#pragma config(Motor,  port3,           lift1,         tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port4,           lift2,         tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port5,           lift3,         tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor,  port6,           lift4,         tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor,  port7,           lift5,         tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor,  port8,           lift6,         tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port9,           frontRightMotor, tmotorVex393HighSpeed_MC29, openLoop, reversed, driveRight)
#pragma config(Motor,  port10,          backRightMotor, tmotorVex393HighSpeed_HBridge, openLoop, reversed, driveRight)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

void setTurnSpeed2(int left, int right)
{
   motor[frontLeftMotor] = left;
   motor[backLeftMotor]  = left;
   motor[frontRightMotor] = right;
   motor[backRightMotor]  = right;
}

void drive(int dist_cm)
{
   static int s_error_thres = 40;
   static int s_drive_spd = 50;
   float set_point = dist_cm * 10.6;
   SensorValue[base_quad_l] = 0;
   SensorValue[base_quad_r] = 0;
   float errorl = set_point - SensorValue[base_quad_l];
   float errorr = set_point - SensorValue[base_quad_r];
   float error_avg = (errorl + errorr) / 2;
   float drive_spd = error_avg >0? s_drive_spd:-s_drive_spd;
   setDriveSpeed(drive_spd);
   while (true)
   {
      float l_spd = drive_spd, r_spd = drive_spd;
      if (abs(errorl - errorr) > 10)
      {
       if (errorl > errorr)
          l_spd += 10;
       else
          r_spd += 10;
      }
      setTurnSpeed2(l_spd, r_spd);
      if (abs(error_avg) < s_error_thres)
      {
         // brake
         setDriveSpeed(set_point>0? -10:10);
         writeDebugStream("===> Drive MID error[%d,%d], set point[%.2f]\n", set_point - SensorValue[base_quad_l], set_point - SensorValue[base_quad_r], set_point);
         break;
      }
      writeDebugStreamLine("Drive in progress: error[%.2f,%.2f], speed[%.2f,%.2f]", errorl, errorr, l_spd, r_spd);
      wait1Msec(20);
      errorl = set_point - SensorValue[base_quad_l];
      errorr = set_point - SensorValue[base_quad_r];
      error_avg = (errorl + errorr) / 2;
   }
   wait1Msec(300);
   stopDriveMotors();
   writeDebugStreamLine("===> Drive LAST error[%d,%d], set point[%.2f]\n", set_point - SensorValue[base_quad_l], set_point - SensorValue[base_quad_r], set_point);
}

#define LEN(array) sizeof(array)/sizeof(array[0])

void testBase()
{
   clearDebugStream();
   int dists[] = {50, -50, 50, -50, 50, -50, 80, -80, 100, -100};
   for (unsigned int i = 0; i < LEN(dists); ++i)
   {
      while (true)
         if (vexRT[Btn7U] == 1)
            break;
      writeDebugStreamLine("Drive dist [%d]", dists[i]);
      drive(dists[i]);
      //driveQuadPid(dists[i]);
      wait1Msec(500);
   }
}



Thu Apr 30, 2015 2:21 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 7 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.