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.

velocity control while doing position control.

i am working on a tracking application where the motor needs to move such that it keeps tracking an object of interest. 

Everytime the system knows where the object is, it gets a desired position which if different from current position, ends up causing a finite value for Position Step. The spintac move calculates a position profile from current position to desired position while keeping within the max velocity, acceleration, deceleration and jerk limits. And follows it as best as it can, it works pretty good but i have two questions

1) Let's say a define position profile is being followed ie its not complete yet, if i want to update the desired destination position , is it possible for spintac move to drop the profile that it was on and just start another new profile based on a new desired destination position  , current position, current velocity while within the max velocity, acceleration, deceleration and jerk limits? I would like the start velocity of the new profile be same as current velocity so the transition is not jerky or stops during transition. 

2) My sensor input rate is not very fast so sometimes the motor goes from pos1 to pos2 , stops at pos2 and then goes to pos3. To make it seemless, It would be great if i provided not only pos2 but also desired velocity at pos2 so that it never comes to standstill as pos2 and just keep moving so that when the pos3 input comes in, it can go for pos3. Is that possible? I do the functions STPOSMOVE_getVelocityStart and STPOSMOVE_setVelocityEnd, I wonder if i can just assigne values to STPOSMOVE_setVelocityEnd while assigning pos2 and then for movement to pos3, i can assign current velocity to STPOSMOVE_getVelocityStart . any sugegstions?

  • 1. SpinTAC Move does not support changing position step while in the middle of generating a position profile.  It also does not support changing from position mode to velocity mode when not at 0 speed.

    2. I'm not sure what you are asking here. What are pos1, pos2, & pos3? Are they position steps? Or are they digital inputs?

  • 1) Fine with it if spintac cant change position step while in the middle of generating a position profile. I can just try to break my big step into bunch of small steps rather give it a big step , so i can stop if a new command comes in that is further away or changed direction of roation. 

    2) This one is very important if we can find a way to make it happen. I ll try again to describe what i was trying to say. 

    Its a case when the rotor has to track and keep moving quickly in harmony with an object that is moving and being detected by a sensor.

    If the object moves slowly ie it only makes changes in position while the velocity stays close to zero at all times then its easy to track. I just keep sending new position steps in +ve or -ve direction based on updated location of the object being tracked. i got this working fine.

    The problem is when the object is moving fast ie velocity is high ( though not so high that the motor cant ever spin that fast to catch up). If the goal is to move from point 1 to point 2 and the speed is zero at point 1 as well as point 2 then the controller does fine if point 1 and point 2 are close to each other. problem is when the object is moving fast and the point1 and point 2 are far apart. Then the sensor sends an updated location at a or many points in between point 1 and point 2. If the sensor waits till object gets to point 2 then it takes a while and the motor will keep thinking the object is at point 1 and cant catch up or gets to point 2 too late. so, Now if i use the points in between points 1 and points 2 as my inputs to the create postion steps them the motor stops at those points because the standard position profile in spintac is designed for zero speed at start and end point. what I need is a way to create a position profile so that the speed at end point is not zero but some finite value that i can provide based on input from my sensor. Is there a way to do so? 

    I noticed in Lab 13e, the STPOSMOVE_setVelocityEnd is used but then STPOSMOVE_setProfileType is ST_POS_MOVE_VEL_TYPE "velocity-determined position profile". In lab 13b, we arent assigning anything to STPOSMOVE_setProfileType , so i am guessing it stays in default ST_POS_MOVE_POS_TYPE "position-determined position profile". Is it possible to use STPOSMOVE_setVelocityEnd and STPOSMOVE_getVelocityStart in ST_POS_MOVE_POS_TYPE "position-determined position profile" or are they just made to work in ST_POS_MOVE_VEL_TYPE "velocity-determined position profile" mode.

  • Ok thanks for the additional explanation.  I think I understand what you are trying to accomplish now.

    It seems like you need to have some sort of knowledge about the speed that your object is travelling between point 1 & 2.  Without that additional information it would be difficult to synchronize the movement of the motor with this other object.  I wouldn't use in between points to generate position steps I would use them to know how fast the tracked object is moving and use that information to setup my profile correctly.

    subrat nayak72 said:
    Is it possible to use STPOSMOVE_setVelocityEnd and STPOSMOVE_getVelocityStart in ST_POS_MOVE_POS_TYPE "position-determined position profile" or are they just made to work in ST_POS_MOVE_VEL_TYPE "velocity-determined position profile" mode.

    STPOSMOVE_setVelocityEnd & STPOSMOVE_getVelocityStart  are only used in ST_POS_MOVE_VEL_TYPE profiles.  There is no way to make SpinTAC Move generate a position profile with non-zero start and stop speeds.

  • great !

    Is it possible to switch from ST_POS_MOVE_POS_TYPE "position-determined position profile" to ST_POS_MOVE_VEL_TYPE "velocity-determined position profile" mode and back ? that may help me get from point 1 to point 2 quickly. so, i can start in ST_POS_MOVE_VEL_TYPE "velocity-determined position profile" mode and then at the end, i can switch to ST_POS_MOVE_POS_TYPE "position-determined position profile" to reach point 2.
  • Yes, you can switch between ST_POS_MOVE_POS_TYPE and ST_POS_MOVE_VEL_TYPE. However you can only do this when at 0 speed.

  • I see, so i can run in ST_POS_MOVE_VEL_TYPE until its time to stop, so i can apply end velocity to zero for the last ST_POS_MOVE_VEL_TYPE profile and then when that profile is done, i can change to ST_POS_MOVE_POS_TYPE profile.  

  • Exactly, that plan would work.

  • In Lab 13e, in ST_runPosMove I changed it to

    void ST_runPosMove(ST_Handle handle)
    {
    ST_Obj *stObj = (ST_Obj *)handle;

    if (flag == false)
    {
    // Run SpinTAC Position Profile Generator
    // If we are not running a profile, and the PosStep_MRev has been modified
    if(_IQmpy(gMotorVars.MaxVel_krpm, _IQ(ST_SPEED_PU_PER_KRPM)) != STPOSMOVE_getVelocityEnd(stObj->posMoveHandle) || (rerun == true))
    {
    // Get the configuration for SpinTAC Velocity Profile Generator
    STPOSMOVE_setCurveType(stObj->posMoveHandle, gMotorVars.SpinTAC.PosMoveCurveType);
    STPOSMOVE_setProfileType(stObj->posMoveHandle, ST_POS_MOVE_VEL_TYPE);
    STPOSMOVE_setVelocityEnd(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxVel_krpm, _IQ(ST_SPEED_PU_PER_KRPM)));
    STPOSMOVE_setAccelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxAccel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
    STPOSMOVE_setDecelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxDecel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
    STPOSMOVE_setJerkLimit(stObj->posMoveHandle, _IQ20mpy(gMotorVars.MaxJrk_krpmps2, _IQ20(ST_SPEED_PU_PER_KRPM)));
    // Enable the SpinTAC Position Profile Generator
    STPOSMOVE_setEnable(stObj->posMoveHandle, true);
    rerun = false;
    }

    }
    else
    {
    if((gMotorVars.RunPositionProfile == true))
    {
    STPOSMOVE_setCurveType(stObj->posMoveHandle, gMotorVars.SpinTAC.PosMoveCurveType);
    STPOSMOVE_setProfileType(stObj->posMoveHandle, ST_POS_MOVE_POS_TYPE);
    STPOSMOVE_setPositionStep_mrev(stObj->posMoveHandle, gMotorVars.PosStepInt_MRev, gMotorVars.PosStepFrac_MRev);
    STPOSMOVE_setVelocityLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxVel_krpm, _IQ(ST_SPEED_PU_PER_KRPM)));
    STPOSMOVE_setAccelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxAccel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
    STPOSMOVE_setDecelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxDecel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
    STPOSMOVE_setJerkLimit(stObj->posMoveHandle, _IQ20mpy(gMotorVars.MaxJrk_krpmps2, _IQ20(ST_SPEED_PU_PER_KRPM)));
    STPOSMOVE_setEnable(stObj->posMoveHandle, true);
    gMotorVars.PosStepInt_MRev = 0;
    gMotorVars.PosStepFrac_MRev = 0;
    gMotorVars.RunPositionProfile = false;
    rerun = true;
    }
    }

    STPOSMOVE_run(stObj->posMoveHandle);
    }

    so by default if flag = false, it runs in velocity mode so the position steps are automatically calculated to maintain whatever was set by setVelocityEnd. now if i change the  flag to true, it should shift to position mode and the position steps should now come from PosStepInt_MRev and PosStepFrac_MRev , right? so then i should be able to manually control it? and then when i make flag back to false, it should switch back to velocity mode where the position steps are automatically calculated to maintain whatever was set by setVelocityEnd. 

    I tried running this but it seems the control never shifts from velocity mode to postion mode, so i cant control it with my manual inputs for PosStepInt_MRev and PosStepFrac_MRev and RunPositionProfile like we do in lab 13b. I even tried to transition when MaxVel_krpm = 0, but it still seems to stay in velocity mode.

    Any suggestions on how to transition?

  • This approach will only work if MaxVel_krpm == 0.  My guess is that there is a bug in the logic.  After configuring the position profile, you set rerun = true which will try to configure a velocity profile.  This doesn't seem 100% correct to me.  My advice would be to remove all automatic switching logic and make sure that you can manually switch between the two different configurations before building the automatic transition logic.

    You can also test for errors by looking at the error code coming out of the Position Move block.

  • Hi Adam,

    Got it all working. the problem was that i was using same variable gMotorVars.MaxVel_krpm for both speed mode and position mode. the trasition works from velocity to position mode only when MaxVel_krpm = 0 but then the position mode wasnt working because MaxVel_krpm = 0. by using two diffrent variables for the two applications, it worked out great. thanks for all the help.

    Now, while tracking the target from one point to another point if the traget is moving fast then the control switches into velocity mode and keeps tracking rather than stopping many times after every discrete position profile and then when the target slows down or stops, then control makes velocity zero in velocity mode and then switches into position mode and keeps centered on the target. it does need a little bit of tuning for what value of speed is high enough to go into velocity mode and depends heavily on the accuracy of the velocity feedback but its working fine.

    I still have to work on the how to make the position controller stop twitching when it has reached close to the desired encoder count ( because of low encoder resolution), I ll ask you questions on another post if I get stuck. thanks a lot and happy holidays!

  • Dear Subrat nayak72,

    I have a similar need like you. How did you resolve this issue with two different variables ?

    I guess it is:

    void ST_runPosMove(ST_Handle handle)
    {
    ST_Obj *stObj = (ST_Obj *)handle;
    
    if (flag == false)
     {
        // Run SpinTAC Position Profile Generator
        // If we are not running a profile, and the PosStep_MRev has been modified
        if(_IQmpy(gMotorVars.SpeedRef_krpm, _IQ(ST_SPEED_PU_PER_KRPM)) != STPOSMOVE_getVelocityEnd(stObj->posMoveHandle) || (rerun == true))
        {
          // Get the configuration for SpinTAC Velocity Profile Generator
          STPOSMOVE_setCurveType(stObj->posMoveHandle, gMotorVars.SpinTAC.PosMoveCurveType);
          STPOSMOVE_setProfileType(stObj->posMoveHandle, ST_POS_MOVE_VEL_TYPE);
          STPOSMOVE_setVelocityEnd(stObj->posMoveHandle, _IQmpy(gMotorVars.SpeedRef_krpm, _IQ(ST_SPEED_PU_PER_KRPM)));
          STPOSMOVE_setAccelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxAccel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
          STPOSMOVE_setDecelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxDecel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
          STPOSMOVE_setJerkLimit(stObj->posMoveHandle, _IQ20mpy(gMotorVars.MaxJrk_krpmps2, _IQ20(ST_SPEED_PU_PER_KRPM)));
          // Enable the SpinTAC Position Profile Generator
          STPOSMOVE_setEnable(stObj->posMoveHandle, true);
          rerun = false;
        }
     }
    else
     {
        if((gMotorVars.RunPositionProfile == true))
        {
          STPOSMOVE_setCurveType(stObj->posMoveHandle, gMotorVars.SpinTAC.PosMoveCurveType);
          STPOSMOVE_setProfileType(stObj->posMoveHandle, ST_POS_MOVE_POS_TYPE);
          STPOSMOVE_setPositionStep_mrev(stObj->posMoveHandle, gMotorVars.PosStepInt_MRev, gMotorVars.PosStepFrac_MRev);
          STPOSMOVE_setVelocityLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxVel_krpm, _IQ(ST_SPEED_PU_PER_KRPM)));
          STPOSMOVE_setAccelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxAccel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
          STPOSMOVE_setDecelerationLimit(stObj->posMoveHandle, _IQmpy(gMotorVars.MaxDecel_krpmps, _IQ(ST_SPEED_PU_PER_KRPM)));
          STPOSMOVE_setJerkLimit(stObj->posMoveHandle, _IQ20mpy(gMotorVars.MaxJrk_krpmps2, _IQ20(ST_SPEED_PU_PER_KRPM)));
          STPOSMOVE_setEnable(stObj->posMoveHandle, true);
          gMotorVars.PosStepInt_MRev = 0;
          gMotorVars.PosStepFrac_MRev = 0;
          gMotorVars.RunPositionProfile = false;
          rerun = true;
       }
     }
     //Call the runtime function 
     STPOSMOVE_run(stObj->posMoveHandle);
      
     return;
    }// end of the ST_runPosMove() function.

    But when and where did you set gMotorVars.SpeedRef_krpm variable to ZERO in your project?

    Thank you for sharing your experience.