EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: NaN and analog records
From: Benjamin Franksen <[email protected]>
To: <[email protected]>
Date: Wed, 5 Nov 2014 12:59:52 +0100
On Tuesday 04 November 2014 10:00:16 Andrew Johnson wrote:
> On 11/04/2014 04:21 AM, Benjamin Franksen wrote:
> > how do you handle a client writing NaN to an analog record (which
> > probably happens by accident)? My intuition tells me that the proper
> > response for the record is to go into an INVALID status, but
> > apparently this is not what happens by default...
>
> Depends on the record type and the version of Base you're using, we've
> fixed some of them...
>
> > The problem with accepting NaN is that subsequent tests (e.g. via
> > calc or sub record) may give wrong results, perhaps leading to
> > motors starting to move when they should not (it happened to us,
> > which is the reason why I write this).
>
> Writing any kind of code that handles NaN and Inf values correct takes
> extra thought that many programmers don't do. We have made various
> changes to the Base record types in recent years but I'm sure we
> haven't found all of the issues.
>
> Ralph did some work on alarm limit tests recently for 3.15 so I think
> we're good there, but (since it was raised earlier in this thread) I
> don't remember if anyone looked at the DRVH/DRVL code yet, so here
> goes. These are the first lines in the convert() subroutine [on both
> 3.14 and 3.15 branches]:
>
>     if (prec->drvh > prec->drvl) {
>         if (value > prec->drvh)
>             value = prec->drvh;
>         else if (value < prec->drvl)
>             value = prec->drvl;
>     }
>
> * If either DRVH or DRVL is NaN then the first test will fail so the
> value will not be limited.
> * If the value is NaN, both limit tests will fail so the value will
> remain a NaN. Since NaN is neither low nor high, this makes sense.
> * Further into convert() a NaN value will result in OMOD being set,
> thus triggering VALUE and LOG monitors. I can't say what RVAL will be
> set to as I think that will be implementation dependent.
>
> After convert() returns the process() routine does
>     prec->udf = isnan(prec->val);
> This results in the record being put into UNDEFINED/Invalid or UDFS
> alarm state and can thus trigger the IVOA processing actions.
>
> This seems reasonable to me, any comments?

Thanks Andrew,

as it turned out (I did not observe the failure myself, and perhaps I
misunderstood my colleague) the client wrote the NaN directly to the A
field of the subroutine record with no intervening ao record. Using an
ao record which forwards its value via OUT link to the subroutine
record's A and setting its IVOA to "Dont' drive outputs" would have
prevented the problem. Also, the subroutine record probably *did* become
INVALID, but this wasn't checked by subsequent records which monitored
the subroutine's VAL field.

Furtehr comments:

The way NaNs are handled in the ao record seems reasonable to me, too.
One might question whether it makes sense to actually (try to) convert
when VAL is NaN, but I guess this is a matter of taste.

What about other record types?

Looking at the code (base 3.14.12.2 sources) for sub, calc, and calcout
reveals that they, too, set prec->udf = isnan(prec->val), so I think
these record types are doing the right thing. (I haven't checked this in
depth, though).

One loop hole remains in the ai record: it checks for NaN only inside
the convert procedure. Thus, writing a NaN directly to the ai record's
VAL will not cause the record to become INVALID (assuming INP is empty).
This is perhaps a somewhat non-idiomatic use of an ai record, but there
is nothing to prevent it being used like that, so I guess the check for
NaN should be made directly inside process() like for the ao record.

Cheers
Ben
--
"Make it so they have to reboot after every typo." ― Scott Adams

________________________________

Helmholtz-Zentrum Berlin für Materialien und Energie GmbH

Mitglied der Hermann von Helmholtz-Gemeinschaft Deutscher Forschungszentren e.V.

Aufsichtsrat: Vorsitzender Prof. Dr. Dr. h.c. mult. Joachim Treusch, stv. Vorsitzende Dr. Beatrix Vierkorn-Rudolph
Geschäftsführung: Prof. Dr. Anke Rita Kaysser-Pyzalla, Thomas Frederking

Sitz Berlin, AG Charlottenburg, 89 HRB 5583

Postadresse:
Hahn-Meitner-Platz 1
D-14109 Berlin

http://www.helmholtz-berlin.de


Replies:
Re: NaN and analog records Andrew Johnson
References:
NaN and analog records Benjamin Franksen
Re: NaN and analog records Andrew Johnson

Navigate by Date:
Prev: Re: Record processing during iocInit? Ralph Lange
Next: Re: Record processing during iocInit? Dirk Zimoch
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: NaN and analog records Andrew Johnson
Next: Re: NaN and analog records Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  <20142015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 17 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·