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.

Speed Control in Torque Mode

Other Parts Discussed in Thread: MOTORWARE, BOOSTXL-DRV8301

hi guys,

my question is how can I control the speed in torque mode.

i am using proj_lab04.

the motor drives with the maximum speed.

speed can be reduced when i reducing the dc voltage.

my problem is that the motor must slowly start up with an ramp.

i thought about that i fake the voltage scale factor to control the speed. like this

DRV_setVoltageScaleFactor(drvHandle ,gVoltScale);

but it doesn't work.

the gMotorVars.Speed_krpm change when i fake the scale factor but the real motor speed don't change.

does it gives an another solution?

alex

  • hi, Alex.

    "how can I control the speed in torque mode"

    You cannot. By definition, the act of attempting to control the speed means you are in "speed mode", requeting a change in torque.

    "speed can be reduced when i reducing the dc voltage."

    Certainly. This is actually the way that many hobby ESCs work. They attempt to commutate at near 100% duty cycle and then just vary the bus to adjust the voltage to the motor.  With low inductance, high speed motors this actually works pretty well.  But FOC can do it even better, giving better dynamic performance and higher efficiency (our customers tell us on their full suite of testing they are getting 10-15% more battery life using InstaSPIN-FOC). 

    You really don't want to do this with InstaSPIN-FOC!

    "my problem is that the motor must slowly start up with an ramp."

    This can be done two ways.

    1. If you want to just stay in the Torque control only mode (simpler) you can simply put a Trajectory module inbetween the user input Torque Reference and the Torque command feeding the Iq PI controller.  This Trajectory module is just like the one you would use on the front end of the speed controller, meaning you give it an ending reference and a rate of change (like an acceleration for your Iq reference, how quickly you allow it to change).  Using the Trajectory module in MotorWare you can do constant rate of change, just like a trapezoidal constant acceleration for speed control.  If you needed to so something REALLY fancy you could use SpinTAC Suite and the Trajectory module that lets you also choose S and ST types of curves.  This can be applied to the Torque command as well, giving you a very smooth input into the torque control system.  By having different curves and rates of change / limits you could have different "modes" just like in some cars: high performance, comfort cruising, etc.
      1. I think it's also important that you understand what Torque mode means for FOC. The Torque reference you set to the Iq PI controller is the Maximum Iq current that you will allow the motor to consume. MAXIMUM.  That means if the motor does not need to produce that maximum current/torque it will NOT.  The motor consumes what it needs...and by controlling Id to 0 (typically) and knowing the flux angle you are insuring efficient operation...you are only limiting the maximum.   For example, on an unloaded motor you will get the same power usage when commanding 100% of Iq or something much lower (down to the minimum required to hit full speed).
    2. The other option is to actually use a speed controller in certain cases, like start-up or "cruise" modes.  This is very simple to do using InstaSPIN-FOC by just using the function
      CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);  // or true
      What you have to be aware of is the state of the output of the speed controller and input of the Iq reference as you switch between the two. For example, if you are in Torque mode and want to switch into speed mode, you need to get the input of the Iq controller and set that is the output of the speed PI controller and get the speed estimate and set as the initial reference.  This is to insure smooth transition. 

     

  • hi chris,

    thank you for the very detailed and quick answer. :-)

    i know gMotorVars.IqRef_A is the maximin current.

    When the motor is unloaded it drives with full speed.

    I can reduce the speed when i change the value of gMotorVars.IdRef_A.

    But the current goes high. I see it on an multimeter.

    can you tell me how can i simply control the speed without 

    spintac move or is it too complex?.

    i think its too complex.

    which lab should i take as reference to use spintac move to control speed in torque mode?

    can you give me a little bit help.

    i begin to study lab6a, maybe i will understand more. ;-)

    alex

  • "I can reduce the speed when i change the value of gMotorVars.IdRef_A."

    No, no, no. This is not how you reduce speed. You reduce speed by

    1. loading the motor

    2. reducing IqRef_A

    2a. Add a speed loop which will reduced IqRef_A to meet the speed goal.

    By adding IdRef_A you are saturating the magentic field of the motor and changing your orientation from the ideal 90 degrees to something less. You will lose torque, saturate the iron or your stator, and if you are not careful can permanently damage your motor.  Your total current is given by Is = sqrt ( Iq^2 + Id^2).

    If you add negative IdRef_A you will weaken the field of the motor, reducing the Bemf generated and potentially allowing you to go faster but with less torque. However, the same Is still applies, so you must reduce your IqRef_A to keep Is < rated current.

     

    What exactly are you trying to accomplish?  Why are you not just using a speed loop like proj_lab5b?

     

  • Hi Chris,

    I'll try you to tell you what i want.

    The task is to tight a srew with a defined torque.

    This 2 tests i have done.

    Test 1 (speed loop lab5d)

    This lab runs in speed loop.

    I insert just a simple code in the following Function

    void updateGlobalVariables_motor(CTRL_Handle handle, ST_Handle sthandle)

    gTorque_Nm = EST_getTorque_Nm(obj->estHandle);

    if(gTorque_Nm_shutdown > gTorque_Nm)

    gMotorVars.SpeedRef_krpm = _IQ(0.0);

    When the screw reaches the torque the motor stop quickly.

    But this is not quickly enough.

    The acceleration is set to the maximum.

    I have also testet to disable the pwms after torque is reached.

    if(gTorque_Nm_shutdown > gTorque_Nm)

    DRV_disablePwm(drvHandle);

    Test 2 (torque mode lab04) 

    In this lab all i must do is to set the 

    gMotoVars.IqRef_A to the required torque.

     _iq iq_ref = _IQmpy(gMotorVars.IqRef_A,_IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A));

    i can be sure that the screw is not demolished because gMotoVars.IqRef_A limit the torque.

    This works very well but the motor drives on startup with full speed.

    Which parameter tells the motor how quickly it reaches the full speed.

     I cannot implement an Trajectory module on startup because when the screw is tightend i damaged the screw because the Trajectory module controls the Iq Ref.

    I am thinking about to control the speed over the PFC. Just like hobby ESCs.

    But you write me thats not the very well way.

    I need an solution. Can you help me?

    Alex

  • Alex,

    1. I think you have this backwards:

    if(gTorque_Nm_shutdown > gTorque_Nm)

    You want to shutdown when the gTorque_Nm  >=  gTorque_Nm_shutdown

     

    2. Make sure that you are using

    #define USER_IQ_FULL_SCALE_FREQ_Hz        (4 * USER_VOLTAGE_FILTER_POLE_Hz) 

    as it is critical for accurate flux and torque measurments.  You should also "tune" your SW filter to match the real HW Vph filters on your board. We find that the actual pole is usualy significantly larger than what we calculate it to be.  For example, on my BOOSTXL-DRV8301 I'm using today we designed the pole for 364.68 Hz but mine is actually closer to 390 Hz.  How did I figure this out?  Watch your Flux value as you increase speed.  Once stabilized at a speed note (it will always change during acceleration / loading), if the flux is increasing at higher speeds your SW pole is too low and you need to increase USER_VOLTAGE_FILTER_POLE_Hz (and vice versa if the flux is decreasing).  This is only if you want to get the MOST accurate measurements.  If you really care about high precision you will do this...you would also wan to consider the highest quality / lowest drift capacitors for your Vph.  This is all application dependent, just letting you know about some options.

    3. Also note that it appears we have a Q format / Full Scale bug in the getFlux function, and in large torque applications this value will wrap around (so you will all of a sudden get a negative torque value). This doesn't affect the control - unless you are using the Torque feedback in your own Torque control loop.  This is in our bug system and we are looking at a patch.

    4.  "I insert just a simple code in the following Function. But this is not quickly enough."

    You are doing this in the background loop. If you really wanted to make this happen faster you should put the logic in the main interrupt.

    5. some other ideas:

    Have you tried using a PWM brake function?  When you reach your Torque value you can brake the motor by placing either all high side or all low side FETs ON.  This will cause the energy to recirculate in the motor and is the fastest way to bring the motor to a stop.  It certainly burns the current off in the stator windings though.

    You could also do this using a Trip Zone so it is HW driven and not SW driven.

    Do you really want your driver to STOP when it hits the max torque, or just saturate at the maximum torque allowed, just under the Shutdown value?  It is quite simple to limit the maximum torque through your Iq PID controller.

     

  • Hi Chris,

    Sorry Chris, You are right with this.

    I want to shutdown when the gTorque_Nm  >=  gTorque_Nm_shutdown

    Thats my mistake after renaming the variables.

    My code is correct. the mistake was only here.

    You are doing this in the background loop. If you really wanted to make this happen faster you should put the logic in the main interrupt.

    I think the loop is fast enough. the loop time is about 250us.

    The time ramp where the screw is tightend is about 50ms. so we are fast enough for measurements

    I think the problem is we don't stop the motor fast enough.

    can you tell me how can i do the PWM brake function?

    you prefer to do this project better with speed loop?.

    It is quite simple to limit the maximum torque through your Iq PID controller.

    How can i do this?.

    Alex

  • Alex,

    You can limit the output of the speed PI controller or the output of the Iq PI controller.

    Look at the pid.h

    outMax

    This is usually set to 1.0

    You could dynamically clamp this...but that doesn't seem to be your issue.

     

    For the brake function you would want to create a function that based on your variable (like gBrake == TRUE) would set the PWMs into a state of all high side or all low side switches on.  You would stay in this state until gBrake == FALSE.

    you will need to look at this function to see how the data needs to be configured to write the PWM registers.

    DRV_writePwmData(drvHandle,&gPwmData);

     

  • Hi Alex and Chris,

    I believe the original question bears some consideration, in that for this application it is important to limit the inertia of the system.  With a torque limit (only), the motor may be spinning pretty fast in an "effort" to achieve the torque limit.  When the screw resistance builds up enough to provide the limit torque, the system could have enough inertia to significantly overshoot the actual (not Iq-based) torque.  If he can also limit the maximum speed while in torque mode, he could expect more consistent results from screw to screw.

    I too an interested to hear how this might be provided for.  Thank you for your attention.

    Regards,

    Dave

  • Dave,

    In this case I would look at using InstaSPIN-MOTION. This will allow you to use SpinTAC - which ID's and uses as an input in the velocity controller the inertia - as the front end of your torque controller.  Potentially you could create target trajectories...and maybe you could look at running the trajectory generation NOT at the velocity rate but at the torque rate, essentially bounding the torque command with velocity and acceleration limitations (instead of acceleration and jerk limitations.)

     

  • Dear Chris,

    thank you very much for your patience with us..

    I think we have a basic misunderstanding about our problem. May be we are wrong..

    1.)  We do know (that is the same what Dave stated) that we have an overshot due to the systems high inertia at higher speeds.

    All our measurements are showing that we are getting much closer to our target torque (after the stop) when driving at lower speeds. That is logical since we do not have endless power to stop the system immediately when the torque is reached.

    A good idea is to shorten the motor winding to get a (relative) fast stop.

    All of this physical based behavior is not at all doubted!

    BUT:

    2.) Trajectories

    In my opinion it is not possible to use trajectories because the rise of the torque is completely unexpected (random) with a very high slope (5 to 100% approx. 30ms). It may happen right from the start (if someone tries to unscrew with high torque or after some Seconds). But we have to react correct in both cases - and we did not know what we should attend. We tried to figure out a trip point at that we are changing from a loose screw to the beginning of the tightening. But this is not possible since you do not always have the same conditions (e.g. a new screw with crease on its thread - or a old rusty one..). 

    That means in other words: THE TRAJECTORY (of Speed or Torque) CAN NOT BE PREDICTED IN ANY CASE.

    The ideal controller has to be very dynamic in means of  torque but limited in case of speed at the same time. Exactly like it is when we adjust the voltage of the intermediate circuit.

    How could we "fake" that (make the controller believe that there is a lower voltage in this circuit)? 

    We tried to put a variable in all paths of the voltage measurement but it did not help. I guess because the controller "knows" the voltage over the current feedback..

    Do you have any ideas about that?

    Best Regards

    Ralf

  • "How could we "fake" that (make the controller believe that there is a lower voltage in this circuit)? "

    You can use the OverModulation variable from proj_lab10 to adjust the maximum duty cycle allowed on the fly. This will saturate/clip your Vs to the value. The default is 1.0 per unit, and in proj_lab10 you can adjust this for OVER-modulation up to 1.33.  I think what you are trying to do is use this for UNDER-modulation.

    So, if you want to emulate that your bus voltage is now half the voltage, you could set to (1.33 / 2) = 0.666

     

  • Ralf, 

    I think the SpinTAC controller would work very well to give you a controller that is very dynamic in terms of torque, but can also be limited in terms of speed.  There is a configuration input to SpinTAC that will limit the maximum velocity it will attempt to control to.  Regardless of what the input velocity is, it will limit to the configured velocity maximum.  

    You would also get a controller that can be very dynamic and responsive to torque demand.  There is also on output maximum setting that will limit the amount of current that the speed controller will attempt to apply.

  • Dear Adam,

    that sounds great.

    We haven't experimented with the SpinTAC Controller so much yet. Could you suggest a LAB Unit that we can modify for testing our needs?

    Which are names of the torque and the maximum velocity variable?

    Best Regards.

    Ralf

  • Ralf,

    The lab I would recommend that you modify for your testing is InstaSPIN-MOTION Lab 05e.  This lab implements the SpinTAC controller with the ramp trajectory generator.  

    STVELCTL_setOutputMaximums is the function that modifies the maximum torque output of the SpinTAC controller.  This function can be called at any point during operation.

    STVELCTL_setVelocityMaximums is the function that modifies the maximum velocity reference value.  This function can only be modified while the SpinTAC controller is disabled (st_obj.vel.ctl.ENB = 0).

  • Hi Adam,

    thank you very much for your advices

    I tested the STVELCTL_setOutputMaximums Function.

    This works very well.

    Now I want to stop the Motor quickly when it reaches the Maximum.

     When I load the Motor the Motor tries to turn further.

    Then when i removed the load the Motor speed rises quickly high and then goes to normal speed reference.

    How can I do when i reached the maximum to stop the Motor quickly

    I think an solution is to check the speed. When the speed goes to zero then I set the Reference Speed to zero.

    Ist this an solution?.

    Alex

  • Alex,

    That would be a good solution.  Another option is to check when the torque output from the speed controller reaches the maximum, you could then set the speed reference to zero.

  • in either case I would consider making "CheckForStall" and "Stalled" states.

    Check for stalls: High torque, near 0 speed, with non 0 speed ref

    Stalled: set a 0 speed / torque command. Logic on how to exit state.