Possible to list all variables from InstallationTab?

As the title says, I just wan’t to know if I can get all the variables from the installation tab?
is it connected to DataModel class, if so then how do I do?

It is currently not supported by the API (API v. 1.1.0),
However the variables are all sent and updated through the Primary Client interface, so it might be possible to read these messages.

1 Like

Can you please go into more detail about how to get this via the primary interface?

It’s not very straight forward to say the least.
You can start in Primary interface documentation excel file.
Look for GlobalVariablesSetupMessage, and GlobalVariablesUpdateMessage. First one is sent whenever new global variable is created (mostly once at the beginning of the program), and then only update messages with new values are sent.

However I see no real value in getting global variables in java part of URCap. @dhv can you be more specific about use case? I suppose you wan’t to populate a list with installation variables, right?

Thanks for the response, @mmi. I can’t speak for dhv, but my use case is that the robot will receive a variable via a socket connection from a third party. I want to capture that variable in my URCap.

In that case, i reckon it would be easier, to just share that variable with a daemon, after it has been received.

E.g.

 # Setup in preamble e.g. from Installation node
xml_rpc_handle_to_internal_daemon = rpc_factory(......) 

# At point of interest in program flow
variable_of_interest = socket_read_ascii_float(1,"mySocketToExternalDevice") # Or other socket_read_ command
xml_rpc_handle_to_internal_daemon.setVariableOfInterestInDaemon(variable_of_interest)
# other code actually using the variable

I have been trying to read the global installation variables from a URCAP as discussed in this forum and have been finding it extremely difficult to say the least! I would like to access the global variables because I want to run a calibration routine with my URCAP and then save the calibrated variables to the data model within my URCAP. I then want to rerun the program and take measurements and adjust the robot path according to the new measurements relative to the calibrated variables in the data model.
Here is what I’ve tried to date:

  1. Initially I tried to do it via the script communicator:
    URCap Sample: URCap-ScriptCommunicator
    however I found that accessing the global variables caused the controller to crash (note I was using a URSIM rather than the real controller but I assume the real controller would do the same). It’s a shame this didn’t work because it would have been a nice simple solution.
  2. @mmi above mentions using GlobalVariablesSetupMessage, and GlobalVariablesUpdateMessage but working out how to do this is beyond my limited programming skills. It seems relatively easy to access variables using the RTDE interface and I’ve gone through the getRobotData sample URCap. However, to access the global variables you need to use the Primary and Secondary Client Interface I’ve struggled to find examples of how to use this with the best one being provided by @ajp here:
    How to process package from robot controller
    Unfortunately it is implemented in python rather than Java and it uses the struct.unpack method – there doesn’t seem to be an equivalent in Java.
  3. I have struggled to understand the daemon method suggested by @jbm above which uses script code and I’m not sure how to access the variable from the URCAP.

Any thoughts or suggestions would be much appreciated.

Been in a similar boat as you regarding accessing the internal registers via the API. It’s just not easy. However, I’m questioning your point number 1: Script communicator crashing the controller. This is VERY common and has, in my experience, always been due to a syntax error. Maybe you forgot a parenthesis, or didn’t capitalize the T or F in True or False. There’s a bunch of little things that have bitten me in the butt before. I would advise printing your entire script command to the console to verify it actually is what you want. You can then screenshot it and post it here if it’s still not working

Many thanks for your reply. The code that I used for testing was very simple. I created an installation variable called “Test” and implemented the following code:

exportTestCommand.appendLine(“sensePointOri1 = Test”);
String sensePointOri1x = exporter.exportStringFromURScript(exportTestCommand, “sensePointOri1”);
System.out.println(sensePointOri1x);

As per your commend above I checked that the installation variable was ‘Test’ and not ‘test’. The code works find when implemented with a script node. The println statement at the end was a simple way of checking whether the code worked – which it didn’t because the system crashed. I am using an old CB3 controller but I also checked it out on the e-series and the same problem occurs.

For a sanity check I implemented the following code:

exportTestCommand.appendLine(“sensePointOri1 = 4”);
String sensePointOri1x = exporter.exportStringFromURScript(exportTestCommand, “sensePointOri1”);
System.out.println(sensePointOri1x);

This worked and gave the expected output of 4 and the system didn’t crash! Any thoughts?

Sounds like the variable is not accessible until runtime. So the script you’re sending sees “Test” and crashes because it has no idea what that is. I remember seeing somewhere else on the forum where it was mentioned that the variables don’t really exist until the program is running.

Thanks for that. After sending the last message I came up with the same conclusion. One additional thing I tried was running the script communicator while the program was paused and I still got the same response.
So, I guess the best solution is accessing the global variables through the primary and secondary client interface. Are you aware of any examples of doing this with Java?

Correct me if I’m wrong here, but I was pretty sure using the script communicator IS using the primary/secondary interface. It has functions for “setAsPrimary()” and “setAsSecondary().” Secondary is capable of running in parallel with the main robot program, it just can’t consume any robot time (no waits, moves, etc). Getting the variable value should be fine, provided it existed. Again, the program would have to be running for the secondary interface to do much. Near as I’ve found, you really can’t interact with variables using Java unless you’re just changing the value via normal script sending, or using variables you’ve created inside the script you send via the scriptCommunicators.

However, check this post: Possible to obtain the value of variable on dashboard server

In which a user claims to be able to read values of variables through the dashboard server. There’s another git repo out there somewhere that includes everything needed to launch the dashboard from Java, so maybe you could use these methods to get what you need? Extremely convoluted, and doesn’t seem like it should be that hard, but I think it is.

Thanks for that. I tried setting as secondary as you recommended but the same problem occurred. I found that the command:
sender.sendScriptCommand(exportTestCommand);

doesn’t crash the robot but it doesn’t work either.
I will have a look further next week, but this simple requirement appears to be rather difficult to solve. The dashboard server looks like it might be fairly complex as well.

Yeah the dashboard server sounds complex, but I know there’s a class file floating around somewhere. I’m sure I found it somewhere else on the forum or github. it simplifies it all down to just having you do things like “dashboard.connect()” and then “dashboard.sendcommand(“command”).” I can’t remember where I found the file though, sorry.

Many thanks. I found these two posts:

Is this what you were thinking of or was it something else?

Thanks for your help and putting me in the right direction and I believe it is now solved - it wasn’t that hard in the end. I created a variable called “Test” and it was possible to read it from the URCAP with the following code. Note that you have to make sure you run the controller first which initialises the variable. I ran the code with a button on the URCAP and it was not necessary to use EventQueue.invokeLater. @vl4dutz_1 provided a lot of good tips in the posts above.

private void saveVariables2() {

	String command = "getVariable Test"+"\n";
	try {
		Socket rt = new Socket("127.0.0.1", 29999);
		System.out.println("socket connected");
		if (rt.isConnected()){
			
			BufferedReader readerFromURScript;
			
			readerFromURScript = new BufferedReader(new InputStreamReader(rt.getInputStream()));
			String inputString = readerFromURScript.readLine();
			System.out.println(inputString);

			DataOutputStream outStream;
			outStream = new DataOutputStream(rt.getOutputStream());
			
			// Send command
			outStream.write(command.getBytes("US-ASCII"));
			System.out.println("Command sent");
			outStream.flush();

			inputString = readerFromURScript.readLine();
			System.out.println(inputString);
			
			// Perform housekeeping 
			readerFromURScript.close();
			outStream.close();
		}
		rt.close();
		
	} catch (UnknownHostException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}
1 Like