View unanswered posts | View active topics It is currently Thu Oct 02, 2014 2:28 am






Reply to topic  [ 2 posts ] 
Encoder Position.... 
Author Message
Rookie

Joined: Sat Mar 01, 2008 3:44 am
Posts: 5
Post Encoder Position....
Hi Everyone,
I’m writing a program that:
• Turn motor A to right and measure the distance.
• Return motor A to its original position (which supposes to be zero).
• Turn motor A to left and measure the distance.
• Return motor A to its original position (which also supposes to be zero).
The problem is that: the encoder value doesn’t return to its original position and after a while the accumulated shift has increased which causes some problems.
Here is the code:

Code:
int leftDistance(tMotor mName, int mSpeed, int mAngle, bool mReturn){

   nMotorEncoder[mName] = 0; //reset the encoder
   motor[mName] = -1*mSpeed ; //speed
   while(nMotorEncoder[mName] > -1*mAngle){} //loop
   motor[mName] = 0; //stop

   //get the distance here
   wait1Msec(600); //to get the value
   int dis = SensorValue[sonar];
   if(dis >= 250){
      dis = 250; //infinity
   }

   //return to your position
   if(mReturn){
      //back to original direction
      motor[mName] = mSpeed; //speed
      while(nMotorEncoder[mName] < 0){}//loop
      motor[mName] = 0; //stop
      nMotorEncoder[mName] = 0; //reset the encoder

   }//if

   return dis;
}//rotateLeft
int rightDistance(tMotor mName, int mSpeed, int mAngle, bool mReturn){

   nMotorEncoder[mA] = 0 ;//reset the encoder
   motor[mName] =  mSpeed ; //speed
   while(nMotorEncoder[mName] < mAngle){} //loop
   motor[mName] = 0; //stop

   //get the distance here
   wait1Msec(600); //to get the value
   int dis = SensorValue[sonar];
   if(dis >= 250){
      dis = 250; //infinity
   }

   //return to your position
   if(mReturn){
      //back to original direction
      motor[mName] = -1*mSpeed; //speed
      while(nMotorEncoder[mName] > 0){}//loop
      motor[mName] = 0; //stop
      nMotorEncoder[mName] = 0; //reset the encoder

   }//if
   return dis;
}//rotateRight


I tried to use nMotorEncoderTarget instead; however, I got the same result. So could please guide me how to do it more accurately?

Thanks
Best Regads,
Asma


Fri Mar 07, 2008 9:23 am
Profile
Rookie

Joined: Mon Oct 29, 2007 4:25 pm
Posts: 7
Location: Potsdam, Germany
Post Re: Encoder Position....
In order to avoid encoder drift, you want to remove the encoder reset from your return blocks. You wait until encoder value zero is reached and then stop the motor and reset the encoder to zero. If the commands execute fast enough, then the encoder value is still zero when you reset it. In this case the command is useless. If execution is not fast enough, then encoder value will drift with respect to physical position.

You could use the nMotorEncoderTarget variable in order to perform the task. However, be aware that the value is not understood as absolute target position but as a number of encoder increments to advance.

This has some drift implications as well. Consider the ROBOTC example NXT Position Control with the suggested "hand of a clock" robot design. You will find that you can create a permanent delay in the hand by blocking it for one or more loop iterations. For a clock, such relative, incremental position control is not really an ideal solution. Absolute control is better.

However, I do not know of a smart way to implement it. My solution consists of a PD control that forces the moter to go to a given absolute encoder value.


Code:
task PDA()
{
   int nE = 0;         // Fehler (offset)
   int nEalt = 0;      // alter Fehler (previous offset)
   int y = 0;          // Stellgroesse (action)
   float fKp = 10;      // Kp Faktor Proportionalglied
   float fKd = 400;      // Kd Faktor Differentialglied
   int nTa =10;        // Ta Zeitschritt

   while(true)
   {
      nE = t - nMotorEncoder[motorA];
      y = fKp*nE + fKd/(float)nTa*(nE-nEalt);
      nEalt = nE;
      if (y > 100) y = 100;
    if (y < -100) y = -100;
    motor[motorA] = y;
      wait1Msec(nTa);
   }

}

task main()
{
   bFloatDuringInactiveMotorPWM = true;
   motor[motorA] = 0;
   nMotorEncoder[motorA] = 0;
   nMotorEncoderTarget[motorA] = 0;
   StartTask(PDA);
   wait1Msec(1000);
   while(SensorValue(soundSensor)<80)
   {
      //nMotorEncoderTarget[motorA] = t;
      t = random(360);
      wait1Msec(500);
   }
   StopAllTasks();


}


This code implements an absolute position control for motorA. The example sets the motor to a random angle every 500 ms.

You can go to any absolute target encoder value by setting t to that value. There will be no drift due to overshoot or external influences.

Best regards, Martin Kraska


Sat Mar 08, 2008 8:37 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 2 posts ] 

Who is online

Users browsing this forum: suldanov 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.