This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

encoder resolution - spintac position controller

Adam  will probably be able to answer this best.

I have tried using the spintac position controller for many motors with different number of poles and different encoder counts per rev (cpr). What i have observed is that things work pretty well when the number of poles is small and encoder cpr is really high. But motors with high pole count and encoder cpr low its really hard to have well tuned stable position controller hold position. The motion profile from point A to point B works great but while holding position, it keeps jittering. changing bandwidth doesn't really help, it just makes the jitter more vigorous while amplitude of jitter stays low. i managed to make things little better by changing the inertia and friction values compared to what was estimated, but it didn't make sense to change the current controller gain or inertia or friction too much from what was estimated. 

Let's say its a case where my encoder resolution is 0.5 degree, which isnt very high cpr. What that means is that if i want it to get to Point B , its ok if the final destination is at PointB + - 0.5 degrees. The rotor should just get to the best closest position close to PointB and call it mission accomplished and just stay there ie hold position and not move a lot on its own unless some external force moves it. But, i have not been able to make that happen. 

I have tuned pid position controllers before for high pole count motors and low cpr encoders and by tuning the p, i and d gains i have managed to make it less jittery while holding position but with the spintac controller i dont have much parameters to play with. 

I always think that there should be a "good enough position" criteria which may be 1 encoder tick or more because mechanical systems will never ever be able to attain a perfect encoder count . So, that if the rotor reached a point that is good enough close to the desired destination it will stop trying hard and be perfect. 

so, is there a place in the spintac position code where i can define such a criteria so that if the difference between the current encoder count and desired encoder count is less that n, it will stop position control or may be reduce the torque ( Iq_ref) down to zero. and when something moves the rotor out of this window such that the difference becomes greater than n, the  position controller kicks in and determines the iq_ref desired to bring it back into the window? 

I think that will help reduce jitter and hold position well in cases if high pole count and low encoder cpr. 

  • Subrat,

    Thanks for the suggestion.  

    The SpinTAC controller is designed to always reach the goal position.  It will attempt to drive the axis in order to match the reference.  For systems with low resolution, there are a couple things you could do in order to help resolve this issue.

    My recommendation would be to modify the position reference (by adjusting SpinTAC Move's position start) after the profile is completed.  This will make it so that the controller can reach the goal position else it will be continuously hunting.

    In order to achieve the behavior you describe in a PID controller you are either making sacrifices with respect to the control performance or are introducing complication by having a "on target window" or introducing some form of gain scheduling.  Either way you are making the controller more difficult to use and more difficult to debug.  

    SpinTAC offers a much simpler and higher performance option where the knobs have been reduced to allow you to achieve a higher degree of performance.  By modifying the reference signal you are not sacrificing anything in terms of controller performance and are able to reduce the "hunting" behavior.

  • Thanks Adam.

    I am trying to comprehend what you meant by "modify the position reference (by adjusting SpinTAC Move's position start) after the profile is completed" while looking at lab13b.

    How will i know that the profile is completed? is it when : gMotorVars.RunPositionProfile = false; ?

    I have noticed that gMotorVars.RunPositionProfile becomes false and then rotor keeps jerking , I can see the current encoder count keeps changing. I am guessing the desired encoder count gets calculated by STPOSMOVE_setPositionStep_mrev, so the rotor keeps trying to find the goal postion.

    How do I modify the position reference? Is it at end of the postion profile ?
    the code makes
    gMotorVars.PosStepInt_MRev = 0;
    gMotorVars.PosStepFrac_MRev = 0;
    gMotorVars.RunPositionProfile = false;

    So, I am still not sure where can i modify the position reference? did you mean in STPOSCTL_setPositionReference_mrev() ?

    In ST_runPosCtl, I see the STPOSCTL_setPositionReference_mrev(stObj->posCtlHandle, STPOSMOVE_getPositionReference_mrev(stObj->posMoveHandle));
    I dont know how does STPOSMOVE_getPositionReference_mrev(stObj->posMoveHandle) calculated? I am guessing its created by STPOSMOVE_setPositionStep_mrev(stObj->posMoveHandle, gMotorVars.PosStepInt_MRev, gMotorVars.PosStepFrac_MRev);

    so, should i just assign zero to STPOSCTL_setPositionReference_mrev() ?

    Will that make iq_ref using CTRL_setIq_ref_pu() to zero?
  • subrat nayak72 said:
    How will i know that the profile is completed? is it when : gMotorVars.RunPositionProfile = false; ?

    You could use that or also this comparison

    STPOSMOVE_getStatus(stObj->posMoveHandle) == ST_MOVE_IDLE

    subrat nayak72 said:
    I have noticed that gMotorVars.RunPositionProfile becomes false and then rotor keeps jerking , I can see the current encoder count keeps changing. I am guessing the desired encoder count gets calculated by STPOSMOVE_setPositionStep_mrev, so the rotor keeps trying to find the goal postion.

    The reason it keeps on moving is that due to the low feedback resolution there is quite a lot of quantization that is seen at the final mechanical position.  So each time the encoder goes up a count or down a count it overshoots the setpoint.  Essentially, the setpoint cannot be reached since it is between two quantization steps.

    What I was referring to is that you could do something like the following code.

    if(<one shot check that on this sample you finished the position movement>)
    {
      STPOSMOVE_setPositionStart_mrev(stObj->posMoveHandle, STPOSCONV_getPosition_mrev(stObj->posConvHandle));
    }

    This will force SpinTAC Position Move to update the current position reference to be the feedback position.  It is important that you only do this on the sample where the profile finishes otherwise you won't have any control since it will be always forcing the reference equal to the feedback.

    subrat nayak72 said:
    I dont know how does STPOSMOVE_getPositionReference_mrev(stObj->posMoveHandle) calculated?

    The incremental position references are calculated in the function: STPOSMOVE_run(stObj->posMoveHandle);

  • thanks for the inputs Adam. I have quite some options to play with now. Let's see how it works when i try these things.

    FYI, i tried to reduce the I gain of the current controller and increase the p gain of the current controller and for the same spintach bandwidth and same inertia and same friction, same encoder with low resolution , the jittering while holding postion came down a lot to being not visible at all. encoder counts were oscillating just by 2 tickets, each tick being 0.08 degree. so that looked great but i think my spintac bandwidth is too low because when i displace it by hand, it oscillated quite a bit in amplitude before settling down to final position even though it settles down after 1 swing, it still overshoots. I need the postion controller to not overshoot at all. if i increase the bandwidth it starts jittering while holding position.

    I will try what you suggested and if that works and keep the jittering negligible while holding position, i should be able to increase the bandwidth to make it more stiff. let's see.
  • Also, let's say i want to move rotor to a new_position and also make sure my velocity of the rotor when it gets to the new postion is new_vel. Is there a way to do that?

    the new_postion is being set by STPOSMOVE_setPositionStep_mrev()

    how will the new_vel be assigned ? Will STPOSMOVE_setVelocityEnd() can be used for that?

    I dont see STPOSMOVE_setVelocityEnd being used in lab 13b so i am assuming when it stops at new_position , the path planner makes sure the velocity at the new_postion is zero. right?
  • subrat nayak72 said:
    I dont see STPOSMOVE_setVelocityEnd being used in lab 13b so i am assuming when it stops at new_position , the path planner makes sure the velocity at the new_postion is zero. right?

    Correct.  Lab 13b assumes that you are doing point-to-point position moves that have a start and stop velocity of 0.  There is another mode you can use the position profile generator in that will allow you to command a velocity.  It is detailed in lab 13e.