Hello, I am a little confused about the parameter setting of GFLIB_IntegratorTR_F32 function.
From the AMMCLIB manual, I get the information shown in the figure below.
But the setting from the example shown here is different. Please see the picture below.
Support the max motor speed is Nmax, and from the AMMCLIB manual, I know that Emax is Nmax*(2*pi/60)*pp, where pp is the pole-pairs and Emax is the max electric speed of the motor. Umax is 2^31 for the f32 format.
So I think the value for the f32C1 parameter should be (Ts/2) * (Nmax*(2*pi/60)*pp) / (2^31) * 2^(-u16NShift). And the value for u16NShift parameter should be calculated according to the equation 4.
But unfortunately, I got an error using the parameter calculation method shown above.
The setting in the second figure works, namely f32C1 is equal to ((Ts/2)/pi)*(Nmax*(2*pi/60)*pp)*(2^31) and u16NShift is equal to 0. Can anyone give a detail explanation?
Solved! Go to Solution.
Hello,
scaling of the physical quantities ensures that the fixed-point fractional values at the input and output of the integrator are always in the fractional range [-1; 1). The C programming language does not support fractional number format so we convert our fractional numbers to their integer equivalents (by shifting the radix point after the least significant digit). Conversion between fractional and integer number format is not scaling - it is the same set of binary digits, only the radix point changed position.
The physical quantities (speed, angle) can be expressed in whatever units you want as long as you express the scaling constant in the same units.
In your example, you expressed the desired speed in mechanical revolutions per minute (RPM) and the maximum motor speed is Nmax = 2000 RPM. You then decided to recalculate the mechanical RPM to electrical radians per second (rad/s). This implies that the rotor angle will be expressed in electrical radians. Recalculation from mechanical RPM to electrical rad/s is not scaling - we still work with physical quantities, only they are now expressed in different units.
If the input to the integrator is expressed in electrical rad/s, the input scaling constant must be also expressed in el. rad/s:
Emax = Nmax*pp*2*pi/60 = 2000*2*2*pi/60 = 418.9 el. rad/s,
where pp = 2 is the number of pole pairs.
Note that 418.9 el. rad/s is the maximum speed you can feed to the integrator - in your schematic, it looks like you are feeding in 2000 el. rad/s which is beyond the maximum and therefore an invalid value.
Assume that we want to integrate the speed which is e.g. 60 RPM. This will require two steps:
1) Recalculate RPM to el. rad/s:
N_rpm = 60 RPM
N_radps = N_rpm*pp*2*pi/60 = 60*2*2*pi/60 = 12.57 el. rad/s.
2) Scale the input to the fractional range and feed it to the integrator:
f32In = N_radps/Emax = 12.57/418.9 = 0.03, which corresponds to the Q1.31 integer 64424509.
If the integrator integrates el. rad/s, the output angle will be expressed in electrical radians, i.e. the output range is [-pi, pi). To scale this range to the fractional range, we must set the output scaling constant to:
Umax = pi
the unit is the same as the output, i.e. electrical radians.
Finally, the scaled integration coefficient is:
C1f = Ts/2*Emax/Umax = Ts/2*(Nmax*pp*2*pi/60)/pi
If the coefficient value fits in the fractional range, we can set u16NShift = 0 and the above value of C1f does not need further shifting by u16NShift. The coefficient can be converted from fractional format to the Q1.31 integer format by shifting the radix point after the least significant bit:
C1f_integer = C1f*(2^31)
Attached is a screenshot of an example integrator with input speed of 60 RPM, Ts = 1 ms, the simulation runs for 1 second. We can see that the integrator output correctly completes two electrical revolutions.
BR,
Petr
Hello,
scaling of the physical quantities ensures that the fixed-point fractional values at the input and output of the integrator are always in the fractional range [-1; 1). The C programming language does not support fractional number format so we convert our fractional numbers to their integer equivalents (by shifting the radix point after the least significant digit). Conversion between fractional and integer number format is not scaling - it is the same set of binary digits, only the radix point changed position.
The physical quantities (speed, angle) can be expressed in whatever units you want as long as you express the scaling constant in the same units.
In your example, you expressed the desired speed in mechanical revolutions per minute (RPM) and the maximum motor speed is Nmax = 2000 RPM. You then decided to recalculate the mechanical RPM to electrical radians per second (rad/s). This implies that the rotor angle will be expressed in electrical radians. Recalculation from mechanical RPM to electrical rad/s is not scaling - we still work with physical quantities, only they are now expressed in different units.
If the input to the integrator is expressed in electrical rad/s, the input scaling constant must be also expressed in el. rad/s:
Emax = Nmax*pp*2*pi/60 = 2000*2*2*pi/60 = 418.9 el. rad/s,
where pp = 2 is the number of pole pairs.
Note that 418.9 el. rad/s is the maximum speed you can feed to the integrator - in your schematic, it looks like you are feeding in 2000 el. rad/s which is beyond the maximum and therefore an invalid value.
Assume that we want to integrate the speed which is e.g. 60 RPM. This will require two steps:
1) Recalculate RPM to el. rad/s:
N_rpm = 60 RPM
N_radps = N_rpm*pp*2*pi/60 = 60*2*2*pi/60 = 12.57 el. rad/s.
2) Scale the input to the fractional range and feed it to the integrator:
f32In = N_radps/Emax = 12.57/418.9 = 0.03, which corresponds to the Q1.31 integer 64424509.
If the integrator integrates el. rad/s, the output angle will be expressed in electrical radians, i.e. the output range is [-pi, pi). To scale this range to the fractional range, we must set the output scaling constant to:
Umax = pi
the unit is the same as the output, i.e. electrical radians.
Finally, the scaled integration coefficient is:
C1f = Ts/2*Emax/Umax = Ts/2*(Nmax*pp*2*pi/60)/pi
If the coefficient value fits in the fractional range, we can set u16NShift = 0 and the above value of C1f does not need further shifting by u16NShift. The coefficient can be converted from fractional format to the Q1.31 integer format by shifting the radix point after the least significant bit:
C1f_integer = C1f*(2^31)
Attached is a screenshot of an example integrator with input speed of 60 RPM, Ts = 1 ms, the simulation runs for 1 second. We can see that the integrator output correctly completes two electrical revolutions.
BR,
Petr
How do I set my parameters if I want to get the integration result of 65535 circles through the 32-bit integrator? Suppose my Emax = Nmax*pp*2*pi/60 = 2000*2*2*pi/60 = 418.9 el.rad /s, and my Umax = pi*65535 according to my idea. However, when I run the integrator in keil, it doesn't work. I don't quite understand the reason, looking forward to your reply, I would appreciate it!
The 32-bit integrator overflows when it reaches the maximum value. If you need to express the integrator output in 16-bit fixed-point fractional type, you can use the conversion function MLIB_ConvertPU_F16F32:
#include "mlib.h"
#include "gflib.h"
tFrac32 my_32bit_integrator_output;
tFrac16 my_16bit_converted_value;
my_32bit_integrator_output = GFLIB_IntegratorTR_F32(...);
my_16bit_converted_value = MLIB_ConvertPU_F16F32(my_32bit_integrator_output);
Alternatively, the integrator function is also available in 16-bit fixed point implementation, in which case the input and output are both 16-bit fractional values.
Hi, @petrz_
Thank you for your detailed explanation.
Hello,
Our AMMCLIB expert is out of office.
Next week he will be available and gives you feedback.
Best regards,
Peter