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.

st_obj.pos.conv.Pos_mrev jumps at end of EST_State_Rs state

Genius 5910 points


 When my Servo-controller is started and goes to the init procedure at the end of the EST_State_Rs sometimes. The motor spins. I traced it back to st_obj.pos.conv.Pos_mrev . At the beginning of EST_State it is zeroed. and when the init process is correct. It stays around zero. But sometimes it makes a jump somewhere between -10 and 10 (position counter roll-over??) . So what is feeding st_obj.pos.conv.Pos_mrev ? what can cause this jump? I use a resolver as mechanical feedback the calculated angle is properly stable.

 Someone who can help???

  • st_obj.pos.conv.Pos_mrev is feed from the electrical angle generated by the ENC block.  It uses delta increments of the electrical angle to increase (or decrease) the mechanical angle.  

    Can you describe under what conditions it will jump?

    evs said:
    between -10 and 10 (position counter roll-over??)

    Yes the position rollover is defaulted to 10, so all mechanical angle signals will be between 10 and -10.

  • Hi Adam,

    I use a resolver as feedback and that signal is stable. So I think there is something else that cause this problem. I think there is some internal zeroing that cause the problem.(Position Profile vs Velocity Profile position reference)

     It happens at the end of state EST_State_Rs state. Randomly. Then I the error .st_obj.pos.ctl.ERR_ID = 2002. 

    I try multiple times the following:

     (intr_obj).Flag_enableSys    1
    (intr_obj).Flag_Run_Identify    1
    (intr_obj).Flag_MotorIdentified   1
    (intr_obj).Flag_enableForceAngle   1
    (intr_obj).Flag_enableFieldWeakening 0
    (intr_obj).Flag_enableRsRecalc    1
    (intr_obj).Flag_enableUserParams   1
    (intr_obj).Flag_enableOffsetcalc    1
    (intr_obj).Flag_enablePowerWarp   0

    I I try multiple times sometimes It works sometimes it don't. There is not any patron. even after a complete restart from the controller I got the problem.

    I can also spin my servo(Velocity Profile) . If I do that and stop and start the controller again. I have always this problem.

    But If I do a move(Position Profile) of 5+ rotations after the spin,  then it is random again.

    So what changed?  I modified user.h and USER_Params so I can user variables for the motor data.  I only don't see how that relate to this problem.

     

    Edit: The result is not complete random. It has a preference toward the last startup result.

    Some variables result after a failled statup:

    (intr_obj).CtrlState    enum unknown    CTRL_State_OnLine 
    (intr_obj).EstState    enum unknown    EST_State_OnLine   

    *((intr_obj.st_obj).posCtlHandle)    struct _ST_POSCTL_Handle_ 
    (((intr_obj.st_obj).pos).conv).Pos_mrev    long    -9.38229537
    (((intr_obj.st_obj).pos).ctl).PosFdb_mrev    long    -9.381881177
    (((intr_obj.st_obj).pos).conv).Pos_mrev    long    -9.38229537
    Resolver_IQangle    long    0.8680356741
    (((intr_obj.st_obj).pos).ctl).PosErr_mrev    long    9.268070102
    (((intr_obj.st_obj).pos).ctl).ERR_ID    unsigned int    2002 



  • When the drive is disabled are you still updating the electrical angle that you are providing to the Position Converter?  The Position Converter needs to be ran at all times so that if the motor moves while the drive is off it will update the position start information to Position Move to prevent this exact issue.  As part of your modifications please make sure that the updating of position start for Position Move is still present.

    it might be helpful if you could attach your main source file.  I could take a quick look and help debug.

  • Finally some results!  I have two markings on the motor. At one shaft angle the controllers starts correctly. At an other shaft angle the controllers spins uncontrolled with error 2002. And if I set the shaft at one of these points I can reproduce the the result.

    So I was thinking is my resolver feedback correct?

    My resolver is calculated at 160khz in the CLA unit. This is started at the beginning of the program and never stops.

     In MainISR the resolver signal is feed in the controller. The Resolver signal is bound  between 0 - 1 and that is 0 - 360 of the shaft.

    Code in MainISR:

         ENC_ResolvercalcElecAngle (intr->encHandle,CLA_Read_Resolverangle ());

    Code of called function:

    // Calculate the Electric angle for resolver signal.
    void ENC_ResolvercalcElecAngle(ENC_Handle encHandle,uint32_t angle)
    {
        ENC_Obj *enc;


      // create an object pointer for manipulation
      enc = (ENC_Obj *) encHandle;

      // compute the mechanical angle
      // add in calibrated offset
      angle += enc->enc_zero_offset;
      // convert to electrical angle
      angle = angle * enc->num_pole_pairs;
       // wrap around 1.0 (Q24)
      angle &= ((uint32_t) 0x00ffffff);
      // store encoder electrical angle
      enc->enc_elec_angle = (_iq)angle;
      // update the slip angle
      enc->enc_slip_angle = enc->enc_slip_angle + enc->incremental_slip;
      // wrap around 1.0 (Q24)
      enc->enc_slip_angle &= ((uint32_t) 0x00ffffff);
      // add in compensation for slip
      angle = angle + enc->enc_slip_angle;
      // wrap around 1.0 (Q24)
      angle &= ((uint32_t) 0x00ffffff);
      // store encoder magnetic angle
      enc->enc_magnetic_angle = (_iq)angle;

      return;
    } // end of ENC_calc_elec_angle() function

    There is no documentation how this is done. So I assume this is correct. But please check. Especially the pole correction and the range of the angle value.

    Thanks!!

  • I have a couple questions about your angle calculation.  

    Do you need to have the value from the resolver be offset by enc_zero_offset?  Shouldn't it already be aligned to the motor electrical pole?

    For the angle, 1.0 in Q24 is not a valid angle, it should go up to 0xFFFFFF which is just less than 1.0.

  • Finally success!

     I removed angle += enc->enc_zero_offset; from ENC_ResolvercalcElecAngle   and that solved the problem. 

     The offset is added in MainISR:

        if ((EST_getState(obj->estHandle) == EST_State_Rs)
                && (intr->UserParams.motor_type == MOTOR_Type_Pm)) {
            ENC_ResolversetZeroOffset (intr->encHandle,CLA_Read_Resolverangle ());
        }

    The code of the function:

    // Set the zero offset for the resolver signal.
    inline void ENC_ResolversetZeroOffset(ENC_Handle encHandle, uint32_t zeroOffset) {
        ENC_Obj *enc = (ENC_Obj *)encHandle;

        enc->enc_zero_offset = zeroOffset;

        return;
    }

    So moving the resolver Zero to the initialized motor pole is not working.

    In the case the Resolver is not inline with a motor pole. How do I correct for this error? Or how do I verify that the mechanical and the electronic angle are aligned? Or is this not needed because a resolver is a absolute encoder for one turn and the current mechanical angle is read at the initialization process.

  • evs said:
    In the case the Resolver is not inline with a motor pole. How do I correct for this error? Or how do I verify that the mechanical and the electronic angle are aligned? Or is this not needed because a resolver is a absolute encoder for one turn and the current mechanical angle is read at the initialization process.

    My guess is that you would need to use the enc_zero_offset in order to bring the resolver angle in line with the motor pole.  The way to verify is to check the resolver angle when you are forcing the motor into an aligned state (Rs recalibration).  The current electrical angle is read at initialization since it needs to be used for the motor control.

  • Ok, I will look into that.  Thanks for the Help!!