01-09-2013 01:48 PM
Ok, I'm looking for why TestStand is doing what I did not expect.
The first passes "Fail" to "!Step.result.PassFail" and uses a data source of "Step.result.PassFail" this step always Regardless of the value of "Fail"
The second passes "Fail" to "Step.result.PassFail" and uses a data source of "!Step.result.PassFail" and operates as I intended. (Fails if Fail is True).
A brief search yeilded the "Don't do that... negate in code" answers to the old "how to Negate Boolean for Step.result.passfail?" question. But this does not explain the unexpected behavior and I'd really like to understand whats really happening here.
Attached is a simple example that demos the behavior using dialog express vis
01-10-2013 06:25 AM - edited 01-10-2013 06:27 AM
Jeff,
the problem in your first step is that the result "PassFail" is never actually written. What is the variable "!Step.Result.PassFail"? Does it exist?
I would say, no, it does not exist.
But because the expression does not fail (since PassFail is boolean and hence can be negated), you get no feedback that you actually pass nothing to Step.Result.PassFail. You can test this by changing the value if the first steps PassFail default value to True.
The reason why your negation in the data source works is the status expression:
Step.DataSource !="Step.Result.PassFail"? Step.Result.PassFail = Evaluate(Step.DataSource):False, Step.Result.PassFail ?"Passed":"Failed"
As you can see, your expression does NOT equal "Step.Result.PassFail". Hence your negated value of this variable is evaluated as stated in the case-select part (Step.Result.PassFail = Evaluate(Step.DataSource)). This evaluation results in your negated value. Next, the Result is set to either "Passed" (evaluated to True) or "Failed (evaluated to False).
hope this helps,
Norbert
01-10-2013 08:15 AM
01-10-2013 10:01 AM
The result of the expression: !Step.Result.PassFail
is a temporary boolean, the result of the "not" operator operation.
The result of the expression: Step.Result.PassFail
is the pass fail variable itself.
It's arguable that if you use "!Step.Result.PassFail" for an output or in/out parameter, that TestStand should perhaps give you an error or warning.
Hope this helps clarify things,
-Doug
01-10-2013 10:20 AM - edited 01-10-2013 10:24 AM
"!Bool" equals "!bool", as long as you make no case sensitive string compare 😉
Ok, the trick is understanding expressions.
Play a little game with me please. Here are the steps to follow:
1. Open your sequence file Funny.seq. Select step one.
2. In code module tab, select the parameter Error Out value. Current content is "Step.Result.Error". Open the expression editor.
3. In the expression, type "ABC" (including quotation marks). Press "Evaluate". You will see that the expression must either
3. a) point to a container or
3. b) be a container itself.
4. Close the dialogs (cancel expression edit dialog) and open on for the parameter Fail (current value "Step.Result.PassFail"). Open the expression editor.
5. Again, type "ABC" in the expression. Evaluate it again. You will see that the expression must either
5. a) point to a boolean or
5. b) be a boolean itself.
What do we learn from this steps?
"Step.Result.PassFail" is the lookup string for a boolean variable. So the evaluation results in a pointer to a boolean.
"!Step.Result.PassFail" is the negation of a boolean variable. Evaluation will therefore fetch the value of the lookup string (type: boolean) and then negate it. So the result will be a boolean value, but it does not point to the variable "Step.Result.PassFail" anymore! Since the result is boolean, the expression passes evaluation.
That is the reason why "!Step.Result.PassFail" as parameter will NEVER pass the boolean return value of the VI to the TestStand dataset (aka execution).
Let's proceed:
6. Move to step two. Switch to tab "Data Source". Open the expression editor for the data source expression.
7. Again, type "ABC" in the expression. Evaluate it again. You will see that the expression must either
7. a) point to a boolean or
7. b) be a boolean itself.
So, catch up: We have the same issue here as step 5! We are not referring to any variable anymore once the expression gets evaluated!
So why does it work as desired nevertheless?
I gave the explanation in my previous post:
@Norbert_B wrote:
The reason why your negation in the data source works is the status expression:
Step.DataSource !="Step.Result.PassFail"? Step.Result.PassFail = Evaluate(Step.DataSource):False, Step.Result.PassFail ?"Passed":"Failed"
As you can see, your expression does NOT equal "Step.Result.PassFail". Hence your negated value of this variable is evaluated as stated in the case-select part (Step.Result.PassFail = Evaluate(Step.DataSource)). This evaluation results in your negated value. Next, the Result is set to either "Passed" (evaluated to True) or "Failed (evaluated to False).
You make a STRING compare in the first part of the status expression. YOUR data source DOES NOT MATCH the expected string.
So in the TRUE case, you evaluate your new data source and write the result back to Step.Result.PassFail. So essentially, this step (in your case) simply negates the content of Step.Result.PassFail! Next expression will query the boolean value of Step.Result.PassFail and write either "Passed" or "Failed" into the Step.Result.Status....
hope this is now more clear,
Norbert
EDIT: The only weird thing is, that in the first step during execution TS does not create a warning (or error) because you assign a return value of the module to a "True" (boolean value).
One thing you can also do to increase understanding about the "issue": Simply write "True" or "False" (without quotation marks!) into the expression field "Value" for the boolean return value of the VI.....
01-10-2013 09:23 PM
01-11-2013 09:37 AM
C/C++ also does not do what you are expecting. For example, if you have:
void MyFunctionWithAByRefParameter(bool &myparam)
{
myparam = true;
}
and do:
MyFunctionWithAByRefParameter(!var);
You will get a compile error, not the behavior you are wanting. I think it's reasonble to argue that TestStand should perhaps give an error or warning in this case, but there is no precedent for it to work like you expected in a text-based language that I am aware of.
-Doug
01-11-2013 12:51 PM
After duct taping my head and studying your explainations I think I get everything except why TestStand does not protect me from myself in this case. Clearly, my mind does not think in any simillar manner as the TestStand R&D team! Thats my minds problem though not NIs.
The point I was missing is that is a STRING used to look-up a "Data location" (or Whatever you want to call it-) I've caused myself enough headaches with "Fail", "Step.result.PassFail", "Failed" and "Pass" to even try to go into "Parameters" in this context. Wires and Nodes for me! those I understand.
Thanks again
01-11-2013 01:25 PM
No problem. I've also logged a request in our tracking database to have TestStand give an error or warning for this.
-Doug