Hello everybody!
After some discussions at github comments for a pull request (check for floating point error due to insufficient precision by ATILIUS-REGULUS · Pull Request #37 · simplefoc/Arduino-FOC · GitHub), I dicided to open a new topic for this problem, as probably several users are involved.
The problem is the present implementation of the motor angle inside simpleFOClibrary, because of the insufficient precision of the float data type.
In order to avoid naming confusions, as there are different definitions for phase angle, relative angle, absolute angle and so on in the literature, I will use “modulo angle” for the value of the motor angle within one rotation, i.e. for motor angle modulo (2*pi).
The number of rotations of the motor shaft will be called “motor rotations”, which is an integer number.
Finally, the value of the motor angle, which includes all the rotations and which is not reset to 0 after one rotation, will be called “motor total angle”.
Currently the motor angle is implemented as the motor total angle.
One of the main advantages of the motor total angle is the fact, that the distance d, a robot with bldc motor and using simpleFOClibrary has driven, can simply be calculated as: d = motor total angle / (2pi) * (2pi*r) = motor total angle * r, with r=radius of the propulsion wheel.
Also the motor angle is used for open loop calculations inside simpleFOClibrary.
The problem with the motor total angle is the small precision of float, which offers only 23 bits for the fraction part (IEEE 754 Standard).
With a typical bldc motor with 5000 RPM (13 bit) and a typical encoder with 4096 CPR (12 bit), 25 bits are needed within one minute for the coding of the motor total angle.
Using the data type float for this purpose means, that the result will have errors in less than one minute, which makes the float implementation of motor total angle practically useless.
Since the Arduino environment (Data Types in Arduino - SparkFun Learn) offers only 32 bit data types, i.e. no double and no long long, my proposition for solving this problem is, that we use “modulo angle” (as float) and “motor rotations” (as long) and remove the “motor total angle” inside the implementation.
The motor angle is involved in many of the source code files and therefore, this would be a major change.
Please note that the motor total angle can easily be calculated by motor total angle = motor rotations + modulo angle.
For calculating the distance of a robot, the problem can be solved easily by: d = (motor rotations * r) + (modulo angle * r), with r=radius of the propulsion wheel.
Cheers,
Juergen