Read variables set by assignment

Hello everyone. I want to create a simple popup during runtime that informs the operator what values a few key variables are set to, so they can stop the program if they are set incorrectly. The variables are set using the built in assignment function. Is it possible to implement this feature using a URCap directly?
I know how to make the popup, but fetching the values of variables turned out to be more difficult than expected. There is a large document explaining how to make new assignments from Java, but it fails to mention reading those variables again. I thought I could just do model.get(varName,""), but this is only capable of getting variables set with model.set, not those made through regular assignment.
I’m sure this points to a fundamental misunderstanding of mine, but I guess not all variables are created equal.

2 Likes

I have also struggled with this same issue (reading urscript variables via Java). Right now I am looking into setting the value to a general purpose register with urscript and attempting to read it…somehow…? not really sure. I just created a similar post here: Get variable/register value from Java

The values stored in the DataModel have no direct affect, to variables present in the program.
The DataModel values, you access by e.g. model.get() and model.set() are the settings and properties of your node, and may not be related to a Variable present in the program logic and e.g. showing up in the “Variables tab”.

If a variable is present in the program VariableModel (i.e. also selectable from the Variables dropdown in Assignment or the Expression Editor) then you can access this collection by Collection<Variable> variables = api.getVariableModel.getAll().
Now if you wanted to use one of these variables in the URScript, e.g. to show in a URScript based popup, you should use the ScriptWriter to get the resolved name of the variable object. This is due to the fact that the Variable object you have selected, may have been renamed since you selected it.
If I have the variable Variable myVariable from the VariableModel collection, then to use this in URScript, I should do something like:

Variable variable = getSelectedVariable();
if (variable != null) {
	String resolvedVariableName = writer.getResolvedVariableName(variable);
	// Use the resolvedVariableName in URScript
} else {
	// Handle this null somehow
}

Consider checking out the two SDK examples “idletime” and “cyclecounter” which both address working with Variables.

1 Like

I’m sorry, but I’m really not that experienced with java so I have some follow-up questions if that’s alright.
When I have the collection of variables, and the resolved name of the variable, how do I get the value of said variable? All the examples I found use the entire list, and displays that with some sorting, but I don’t want all the variables, just the few that are set by a prompt to the operator.
int varVal = variableCollection.myResolvedVarName.value(); // Clearly incorrect, but you catch my drift.
Also, since getting the resolved variable name requires the scriptWriter, is it only callable within the generateScript-function or can I pass the writer to a subfunction?
Kind regards.

It is not necessarily possible, to get the value of a Variable in Java.
The value is first actually assigned to a variable at runtime, hence it is known in URScript.

E.g. in this Program, it is not possible to get a meaningful resolved value of “SomeVariable” when the program is not running.
However when a program starts running, based on the time, “SomeVariable” will at any time have a unique value.
image

I want the value of the variable at the time the custom program node of the URCap is run. So, say I put my URCap node right before thread 1 in your sample program there, I want the value 5. Is that not possible?
It was my understanding that the function generateScript was run when PolyScope tries to run my program node, thus the value of the variable read could be different every time, depending on what assignments were made before it, but it would still be the correct value. Just like any URScript that uses that variable can read the current value and use it in expressions.

What about:

@Override 
public void generateScript(ScriptWriter writer):
   Variable variable = getSelectedVariable();
   if (variable != null) {
   	String resolvedVariableName = writer.getResolvedVariableName(variable);
   	writer.ifCondition( resolvedVariableName + "> 10"):
   	   writer.appendLine( "popup(" + resolvedVariableName + ",\"" + resolvedVariableName + " is larger than 10\")");
   	   writer.appendLine("halt");
   	writer.end;
   } else {
   	// Handle this null somehow
  }
}

This will show a popup and halt the program.
image

1 Like

I can not find getVariable() function in my Eclipse.
where_is_getVariable
I searched through Maven dependencies → api and there is nothing about variables. Do I have an old version of SDK (1.1.10)?

EDIT: Looks like I do. I changed pom.xml to be dependent on the same version of API as cyclecounter (1.2.56). Does it mean that I will not be able to run it on older controller than 3.4? I created my project with newURCap.sh set to 3.4 originally.

Next step. I got this far. How do I set the value of variable?

@Override
public void closeView() {
	// TODO Auto-generated method stub
	Collection<Variable> x = this.api.getVariableModel().get(new Filter<Variable>() {
		@Override
		public boolean accept(Variable element) {
			return element.getDisplayName().equals("MY_VARIABLE_NAME");
		}
	});		
	x.toArray()[0]._____now_what?
}

You can assign a value to a variable using the ScriptWriter.
The Variable has no actual variable, when no program is running, so you can create the assignment in the generateScript method, using the resolved name of the variable.

You can also save the Variable object directly to the DataModel, if you wish to store it.

I started another thread, because this is one is about getting the value of variable:

I want to get access to Installation variable, which will exist, when no program is running, or I will create it if it does not exist yet. Doing it in ScriptWriter does not have effect, if program is not touched (created or modified).

I’m having some problems when running my URCap using getVariableModel() and getRobotModel(). I always got the NoClassDefFoundError exception at run time, both on Ursim 3.5.3 and Controller Image 3.5.3.

I run the built scriptwrapper example and it works, when I do the same in my example I always get exceptions. I checked in the bundle folder, and the api-1.2.56.jar is present, and is the same I use when building.

There is something I’m doing wrong?

Best regards,

Matteo Timossi @recognitionrobotics

Maybe this is off this specific topic.

I have a custom porgram node with 2 input textfields that on change assigns a Datamodel variabel.
This node, will have (& create by push of button like “pickorPlace” example) a tree containing other custom nodes.
These nodes then have to make use of the to Datamodel variables to use them in the generateScript method - the 2 variables hold IP/port for an external server.

I know this is possible with an installation node, but is there an equal method to:
private HelloWorldInstallationNodeContribution getInstallation() {
return api.getInstallationNode(HelloWorldInstallationNodeContribution.class);
}
(From “HelloWorld”)?

Thanks

SOLVED:

I accedently re-assigned the IP & variable in my URscript to default values.