floating point calculations: best practices

broman973

Member
Join Date
Feb 2013
Location
NJ
Posts
19
I'm writing code in RSLogix 5000 for a 1769-L32E (CompactLogix) PLC. I'm curious of any arithmetic strategies or recommendations to maintain accuracy of floating point (REAL) calculations.

My goal is a custom PID controller capable of the highest output resolution possible using REALs (instead of DINTs shifted to desired significant figures).

Your help is much appreciated!
 
Are you writing your own PID? Just the fact you are using REALs will help a lot. The usual problems people run into shouldn't occur if you are using the built in PID or PIDE except for integrator wind up and there isn't much you can do about that unless you write your own PID.

There are a lot of tricks one learns in a numerical methods class but you need to be more specific because I don't want to write a book.
 
Are you writing your own PID? Just the fact you are using REALs will help a lot. The usual problems people run into shouldn't occur if you are using the built in PID or PIDE except for integrator wind up and there isn't much you can do about that unless you write your own PID.

There are a lot of tricks one learns in a numerical methods class but you need to be more specific because I don't want to write a book.

I wrote my own PIDE add-on (velocity derivation of PID, to be exact) so I can multiplex many tag structures using the same routine. The native PIDE instruction doesn't allow that, and my add-on works fine with the exception of accuracy... if there's better tactics available, that is.

What specifics do you need? I don't know any numerical methods specific to optimizing floating-point arithmetic accuracy.
 
so I can multiplex many tag structures using the same routine

I remember your post last year when you said you were going to try this in the name of saving memory.

While I respect your perseverance, I'm going to bow out of this one.
 
What Every Computer Scientist Should Know About Floating-Point Arithmetic

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

Woa, that's a lot of reading. Not a computer scientist by any means. I was hoping for some clear-cut rules on this forum that I can't seem to find elsewhere. Thx anyway though.

I remember your post last year when you said you were going to try this in the name of saving memory.

Yep. Works very well in the field; validated and everything. Just curious if arithmetic accuracy can be improved.

While I respect your perseverance, I'm going to bow out of this one.

......... k. Thx.
 
How exactly do you need to improve accuracy?
You are only going to run into problems if you are trying to go outside the 'dynamic range' of your floating point numbers in a calculation.

Ex: No problem adding .1 to 1234567, but adding .01 to 1234567 will have no effect.

The numerical range for REALS in RSLogix prior to version 24 is 7.2 digits (not 7 and 2 decimals, but actually 7.2 digits). I seem to recall that another digit was added in v.24 to make the range 8 digits, but I could be mistaken. You can see the 7.2 digit thing by making a rung to just add two floats:
ADD Test_Real_1 Test_Real_2 Test_Real_1.

With 1234567 as Test_Real_1, and 0.01 as Test_Real_2, you will not see any adds. Even with 0.06 as Test_Real_2, but move Test_Real_2 to 0.7, and you will see it starting to add again.
 
Last edited:
As usaul, the aplication wil determine.

There is an output analog card to your PID? Is it 12-bit? Then what is your maximum resolution to your actuator?
 
The big error that most people make it adding or subtracting small numbers and big numbers. A common error we see on this forum is adding 1 to a big number like 16,777,216. The same problem would exist if subtracting. I don't see where this should be a problem in most PIDs.

Floating point numbers have effectively a 24 bit mantissa. This is much greater than the resolution of the analog output cards you are using.

The only time you should run into trouble is if your sample intervals are very very small. A PLC can't possibly sample that quickly so I don't see how you can have a problem.

In motion control there are a few cases where resolution is a problem. Obviously moving from 0 to 16.0 meters with micro resolution approaches the resolution problem mentioned above.
 
How exactly do you need to improve accuracy?

I want to ensure the result of any floating-point arithmetic is as close to the actual math result as permissible. From what understand, floating-point calculations can yield inaccurate results if the order-of-operations or argument-factorization aren't optimized.

Ex: No problem adding .1 to 1234567, but adding .01 to 1234567 will have no effect.

The numerical range for REALS in RSLogix prior to version 24 is 7.2 digits (not 7 and 2 decimals, but actually 7.2 digits). I seem to recall that another digit was added in v.24 to make the range 8 digits, but I could be mistaken. You can see the 7.2 digit thing by making a rung to just add two floats:
ADD Test_Real_1 Test_Real_2 Test_Real_1.

With 1234567 as Test_Real_1, and 0.01 as Test_Real_2, you will not see any adds. Even with 0.06 as Test_Real_2, but move Test_Real_2 to 0.7, and you will see it starting to add again.

After testing your example, Test_Real_1 will accumulate when I make Test_Real_2 = 0.07. Then after trying different values of Test_Real_1, the value of Test_Real_2 that begins accumulation will vary. Can you clarify what you mean by "7.2 digits"? Do you mean significant figures? If so, I don't understand how one arrives at seven "point two" sigfigs...

As usaul, the aplication wil determine.

There is an output analog card to your PID? Is it 12-bit? Then what is your maximum resolution to your actuator?

In hindsight, my question is irrelevant of the application. This is a matter of arithmetic techniques that the PLC's math instructions will benefit from in terms of accuracy.

The calculation in my velocity PID add-on is meant as an example. Consider the following equation where all variables are REALs:

DeltaOutput = (Err - ErrPrev) * PGain + Err * (DeltaTimeInMsecs / 1000) * (IGainInRepsPerMin / 60) + (Err - 2 * ErrPrev + ErrPrevPrev) / (DeltaTimeInMsecs / 1000) * (60 * DGainInMins)

Is there a way to optimize the order of operations or factor the arguments to improve accuracy of the result?
 
Given your application, I wouldn't worry about it. You can heed Peter's point in post #9 by trying to group operations in a way that avoids additions and subtractions of numbers having greatly disparate orders of magnitude.

More importantly, this is for a feedback controller; it should compensate indirectly for any long-term cumulative numerical accuracies (or sampling imprecision) in the PID algorithm. So, don't sweat it too much.

(I'd worry more about getting the windup protection, scaling, initialization, limit checking, etc correct).
 
Last edited:
The only time you should run into trouble is if your sample intervals are very very small.

If you take a look at the equation in post #10, do you see any problem areas? The DeltaTimeInMsecs is 480 msecs: the update time of my analog inputs.

More importantly, this is for a feedback controller; it should compensate indirectly for any long-term cumulative numerical accuracies in the PID algorithm.

What about for short-term numerical accuracies, such as when controlling fast-responding room air pressure? In my application, this process is controlled to setpoint, but air damper modulation was too sensitive. As I tuned the loop (lowered the gains), that's when the integral term of my equation became unresponsive (when IGainInRepsPerMin < 0.05). I know it's a small value, but is there a way to preserve its effect on the integral term using better arithmetic?

(I'd worry more about getting the windup protection, scaling, initialization, limit checking, etc correct).

That was the easy part... lol
 
What about for short-term numerical accuracies, such as when controlling fast-responding room air pressure?

At the rate you're sampling, it shouldn't matter. If you're having a problem controlling a fast-acting process, it's not resulting from a lack of floating point precision.

The discrete velocity form of PID has been successfully used for decades and on processors with far less floating point precision than the one you're using.
 
If you take a look at the equation in post #10, do you see any problem areas? The DeltaTimeInMsecs is 480 msecs: the update time of my analog inputs.



What about for short-term numerical accuracies, such as when controlling fast-responding room air pressure? In my application, this process is controlled to setpoint, but air damper modulation was too sensitive. As I tuned the loop (lowered the gains), that's when the integral term of my equation became unresponsive (when IGainInRepsPerMin < 0.05). I know it's a small value, but is there a way to preserve its effect on the integral term using better arithmetic?



That was the easy part... lol

Make sure your actuator is sensitive enough to small signal changes.

Learned this the hard way on a zone reheat actuator(Belimo I think). It had a non adjustable 2 percent deadband and it would take a 2 percent change in the command to get it to move.

I had to trick my way around it by issuing essentially a 100ms analog pulse greater than the deadband and then release it back to the desired command.
 
DeltaOutput = (Err - ErrPrev) * PGain + Err * (DeltaTimeInMsecs / 1000) * (IGainInRepsPerMin / 60) + (Err - 2 * ErrPrev + ErrPrevPrev) / (DeltaTimeInMsecs / 1000) * (60 * DGainInMins)
In the actual implementation are you using floating point constants (eg 60.0) otherwise the processor may be converting your calculation to integer in the background
 

Similar Topics

I need to check an axis actual travel position, and to compare it to the master travel position. To do this I have to multiply the axis travel...
Replies
6
Views
2,562
We have AOIs for projects, which handle material dosing (by hand or by pipes and pumps), obviously they have comparison between setpoint and...
Replies
50
Views
14,205
Hi eveyone. I need transfer signal from system 1 to DCS via modbus. System 1 only can send 32 bit floating point. DCS receive 16 bit integer. How...
Replies
20
Views
10,586
Hi, In my ladder logic, I've got a data register D60 whose value is -0.001 (when using monitor mode to see values). D406 is 0.250. But then...
Replies
5
Views
1,307
Hi, can anybody tell that how can we move floating point data from one Regiter to another register in Fatek PLC.?
Replies
0
Views
1,550
Back
Top Bottom