I am trying to implement a 1 axis artificial spring using a 3 phase stepper motor, a linear stage and simpleFOC. I have the algorithm working where I set the position and can control the ‘spring constant’ with changing the voltage and using voltage torque control. However, when the spring constant is set to a low value i.e. low voltage, the velocity with which the stage returns to the set position is much slower. Is there any way that I can control velocity independent of the torque loop?
Also a related question which might be pretty basic. For a given voltage in the torque loop, how does the algorithm arrive at the velocity of the motor. Is this determined by the kV of the motor?
The velocity is sometimes provided by the angle sensor directly, and sometimes it is calculated by measuring the angle sensor/encoder or whatever at adequate frequency and calculating it. There is a low pass filter I think.
I don’t know what’s up but depending on how you are changing the voltage, you may be de facto changing the effective P constant of the PID controller that is involved in angle control. I forget if there are two lined up, velocity then angle or not. You could add code to adjust the P constant of the PID controller(s) to compensate for voltage changes. However that won’t work in all cases and PID controllers have limits, if you go too far it will oscillate. If you need more response time, you have to use a different regulatory mechanism, PID controllers are just a bit crude like that, they are just a thing that works, they are not optimal or whatever.
@ssuresh What you need is to decouple torque production and motor velocity. The easiest and most accurate way to achieve this is to control motor torque through current limiting, which SimpleFOC supports if your driver board has current sensing on the motor phases. When you do this, you can specify a value of Iq to the motor, and the SimpleFOC code will use the internal current control loop to target this value, regardless of motor velocity. Iq maps linearly to motor torque, so you can easily set your “spring constant” by specifying Iq. You could make Iq a function of position, velocity, etc, simulating a spring very well.
What is the driver board you are using to control the motor? What microcontroller are you using?
Have you tuned the voltage-based current limiting yet? Do that first. Then use MotionControlType::torque and motor.move(-motor.shaft_angle * spring_constant - motor.shaft_velocity * damping);
Higher spring constant should bounce back and forth faster, higher damping will come to a rest more quickly.
Thanks @wrcman555 @dekutree64 @Anthony_Douglas for your answers. It looks like there may be multiple ways to implement the springiness - one is to use the P term on the PID as suggested by @Anthony_Douglas , the other is to be in position mode and use the voltage (or current ) as function of position as suggested by @wrcman555 and the third is to just use the torque mode and set the torque it to be a function of position ( bypassing the PID loop for velocity and position) . Thanks for the very interesting ideas and I will try all of these to see which works best for this setup. I am using the SimpleFOCshield driver and an Arduino due.
I would point out that those all appear to be essentially identical. The P gain is the relationship between the error and the torque, basically. The other two ways you discussed also change that relationship in basically the same way, I think?
In my project I had a similar requirement and solved it in the way proposed by @wrcman555. Works perfectly fine for me.
The way to do this is what was suggested, control the motor in torque mode and use whatever controller you need on top of that, implemented by you in the void loop. I would suggest you use a PD position controller where the output of this controller feeds the SimpleFOC torque controller. This way you have no weird artifacts in terms of speed or anything like that.