Problems with <Command> Class and probably with a variable's precision.

Hello Guys. That's my first post in the forum.

I'm working on a RTT software to control a SPT (Stationary Plasma Thruster) and my guiding professor indicates Orocos to build it. I'm realling liking the program but I'm having some problems with a Command.

My command does a Voltage Ramp from 0 to the Maximum Voltage (500V and 800V). My program works at 1KHz frequency (PeriodicActivity at 0.001).

My solution is to create a variable 'incrementVoltage' and add the value to the other variable "voltageOut" on every execution of my updateHook() function.

I used this example: http://www.orocos.org/stable/documentation/rtt/v1.10.x/doc-xml/orocos-components-manual.html#id491257

I created a function to test if I'm at the diagnosis.

updateHook() {

    if (inDiagnosis() ) {
        incrementValue()
    }
}

My command function is beginDiagnosis(double time). It changes the inDiagnosis() answer to true and calculates the increment with: increment (it's a double) = 800Volts/(time*1000).

The function endDiagnosis() test if the value is on 800Volts and sets inDiagnosis() to false if reach it.

So, the problem is:

When I use <time = 1 second>. The value reaches 800.8 Volts, With increment 0.800000. WRONG.

When I use <time = 10 second>. The value reaches 800 Volts, With increment 0.080000. OK.

When I use <time = 7 second>. The value reaches 800 Volts, With increment 0.114286. OK.

When I use <time = 6 second>. The value reaches 800.133333 Volts, With increment 0.133333. WRONG.

ALL my variables are double type. In some cases, my program does ONE increment more and I can't discover the reason.

Anyone ever passed through this? I put the frequency at 100Hz and still doesn't work. All variables are Attribute<double>.

Thanks.

Problems with <Command> Class and probably with a variable's pre

Alexandrenagy [..] ... wrote:

> I created a function to test if I'm at the diagnosis.
>
> updateHook() {
> if (inDiagnosis() ) {
> incrementValue()
> }
> }
>
>
> My command function is beginDiagnosis(double time). It changes the inDiagnosis() answer to true and calculates the increment with: increment (it's a double) = 800Volts/(time*1000).
>
> The function endDiagnosis() test if the value is on 800Volts and sets inDiagnosis() to false if reach it.

When is the endDiagnosis() function called?

What happens if you put the check inside the incrementValue() function?
i.e. if incrementValue() pseudo code looks something like:

incrementValue(){
if (value == 800){
//do what is needed to make inDiagnosis() return false;
return;
}
else if (value < 800){
voltageOut += incrementVoltage;
return;
}
else {
//error
}
return;
}

I already discover.It's

I already discover.

It's something connected to the double variable.

I made printf()'s with %.20f.

20 Decimal cases.... And show at the end:

799.99999999999998754.... (and something more). The normal printf() with %f show 800 but it's not the TRUE VALUE.

And now? What should I do to fix this precision? Orocos got long double?

I already discover.It's

I already discover.

It's something connected to the double variable.

I made printf()'s with %.20f.

20 Decimal cases.... And show at the end:

799.99999999999998754.... (and something more). The normal printf() with %f show 800 but it's not the TRUE VALUE.

And now? What should I do to fix this precision? Orocos got long double?

I already discover.It's

On Sun, Nov 29, 2009 at 02:07, <Alexandrenagy [..] ...> wrote:
> I already discover.
>
> It's something connected to the double variable.
>
> I made printf()'s with %.20f.
>
> 20 Decimal cases.... And show at the end:
>
> 799.99999999999998754.... (and something more). The normal printf() with %f show 800 but it's not the TRUE VALUE.
>
>
> And now? What should I do to fix this precision?  Orocos got long double?

That won't fix your problem either. There's no 'double' that can
represent 800 exactly. It's always an approximation. When comparing
doubles for equality, you need to provide an 'epsilon', for example:

double eps= 0.001;
if ( fabs(a - b) < eps ) { /* a and b are equal 'enough' */ }

Peter

I already discover.It's

On Nov 30, 2009, at 03:59 , Peter Soetens wrote:

> On Sun, Nov 29, 2009 at 02:07, <Alexandrenagy [..] ...> wrote:
>> I already discover.
>>
>> It's something connected to the double variable.
>>
>> I made printf()'s with %.20f.
>>
>> 20 Decimal cases.... And show at the end:
>>
>> 799.99999999999998754.... (and something more). The normal printf() with %f show 800 but it's not the TRUE VALUE.
>>
>>
>> And now? What should I do to fix this precision? Orocos got long double?
>
> That won't fix your problem either. There's no 'double' that can
> represent 800 exactly. It's always an approximation. When comparing
> doubles for equality, you need to provide an 'epsilon', for example:

I was under the impression that a double can exactly represent any integer in the +/- 2^31 (maybe 2^32?) range. A quick google search didn't find any supporting evidence though ...

> double eps= 0.001;
> if ( fabs(a - b) < eps ) { /* a and b are equal 'enough' */ }

Agreed.
S

I already discover.It's

On Mon, Nov 30, 2009 at 13:51, S Roderick <kiwi [dot] net [..] ...> wrote:
> On Nov 30, 2009, at 03:59 , Peter Soetens wrote:
>
>> On Sun, Nov 29, 2009 at 02:07,  <Alexandrenagy [..] ...> wrote:
>>> I already discover.
>>>
>>> It's something connected to the double variable.
>>>
>>> I made printf()'s with %.20f.
>>>
>>> 20 Decimal cases.... And show at the end:
>>>
>>> 799.99999999999998754.... (and something more). The normal printf() with %f show 800 but it's not the TRUE VALUE.
>>>
>>>
>>> And now? What should I do to fix this precision?  Orocos got long double?
>>
>> That won't fix your problem either. There's no 'double' that can
>> represent 800 exactly. It's always an approximation. When comparing
>> doubles for equality, you need to provide an 'epsilon', for example:
>
> I was under the impression that a double can exactly represent any integer in the +/- 2^31 (maybe 2^32?) range. A quick google search didn't find any supporting evidence though ...

Maybe you are confusing that:

int i = 800;
double a = 800;
assert( a == i );

Will never fail ? I'm guessing the standard provides some equality
guarantees when integers are involved. This is not the case when the
value '800' is calculated.

Peter

I already discover.It's

On Nov 30, 2009, at 09:33 , Peter Soetens wrote:

> On Mon, Nov 30, 2009 at 13:51, S Roderick <kiwi [dot] net [..] ...> wrote:
>> On Nov 30, 2009, at 03:59 , Peter Soetens wrote:
>>
>>> On Sun, Nov 29, 2009 at 02:07, <Alexandrenagy [..] ...> wrote:
>>>> I already discover.
>>>>
>>>> It's something connected to the double variable.
>>>>
>>>> I made printf()'s with %.20f.
>>>>
>>>> 20 Decimal cases.... And show at the end:
>>>>
>>>> 799.99999999999998754.... (and something more). The normal printf() with %f show 800 but it's not the TRUE VALUE.
>>>>
>>>>
>>>> And now? What should I do to fix this precision? Orocos got long double?
>>>
>>> That won't fix your problem either. There's no 'double' that can
>>> represent 800 exactly. It's always an approximation. When comparing
>>> doubles for equality, you need to provide an 'epsilon', for example:
>>
>> I was under the impression that a double can exactly represent any integer in the +/- 2^31 (maybe 2^32?) range. A quick google search didn't find any supporting evidence though ...
>
> Maybe you are confusing that:
>
>

> int i = 800;
> double a = 800;
> assert( a == i );
> 

> Will never fail ? I'm guessing the standard provides some equality
> guarantees when integers are involved. This is not the case when the
> value '800' is calculated.

That actually works fine for me in both linux and OS X SL. Even if I add something like

double a = 800;
a *= 1.1;
a /= 1.1;
assert( a == i );

I tried with both -O0 and -O3. The assert succeeds both times.

Now if you add some more interesting calculations, I'm sure you can get something close to 800 that will fail the assert. Agreed there.
S

Hi guys!I'm gonna test with

Hi guys!

I'm gonna test with both things.

First: (a - b) < 0.00001 (or a really small number).

and,

Second: (a = a*1.1) and (a = a/1.1) to test the results.

Really thanks for the ideas! At night, I will post it the results.

Hi guys!I'm gonna test with

Hi guys!

I'm gonna test with both things.

First: (a - b) < 0.00001 (or a really small number).

and,

Second: (a = a*1.1) and (a = a/1.1) to test the results.

Really thanks for the ideas! At night, I will post it the results.