How can i store the value of a variable of urscript

Hello all!

Im deploying a URCap of a depaletizing which has some counters declared as global variables in urscript. I want to keep the value persistent as Polyscope does with his own global variables.

I tryied to follow the example of scriptCommunicator and tryied to get the variable from the secondary port but the script command is crashing cause the variable doesn’t exist.

Is there a way to make it simlply?

Thank you very much in advance!

Regards!

I would first check and be very sure the script is crashing for the reason you think it is. Using the script communicator will crash if ANY part of the script is wrong. If you forget a comma, or a closing parenthesis, or a quote, it will crash. I always like to System.out.println() my entire command before I execute it just so I can see exactly what it is sending.

Thank you for your response.

I checked the URScript command, and as long i declare the variable before the script it works properly.

if i delete the declaration of the var “Interlayer_counter” then it crashes and a restart of ursim is required.

Maybe I’m missunderstanding something about the URScript variables… But how can we read the variable value from the URScript program?

Hmm I vaguely remember running into a similar issue, and think I had to resolve it in a very different manner. I think what happens is that the script you’re sending cannot see the actual globally scoped variables, so you’re correct when you say it “doesn’t exist.” Declaring it like you’ve done there is scoping a variable to the script, but then it really has no connection to the main program. So its value is always 25, unless you modify it within the actual script you’re sending, which i doubt is very helpful. Can I ask what your intention is here? Do you wish to save the result as the action of a button press, or just programmatically save it during program execution?

I want to recreate the functionality of the Polyscope variable “keep value from the last run”.

I have some variables declared as global var directly in urscript from the generateScript method. The idea is to get the value from the last execution and declare with that value the next time time the URScript is generated.

Should be easy if that value can be found in the variable window of the program in Polyscope.

image

I will keep looking forward, thank you for your help!

OK I think I’m with you. You are creating that variable through your CAP, and you would like to initialize it with its last value. So what you’re really looking for is a way to update the Java side DataModel with the currently running URScript’s value of that variable, that way next time you execute the program, you can generate the script with something like:

writer.appendLine("Interlayer_counter = " + model.get(last_variable_value, 0));

Does that sound correct?

1 Like

That fits exactly as what is needed!

So do you know how can we get the last_variable_value?

Thank you very much!

Hmm well I mean I made it work, but it’s not pretty nor is it particularly easy. Not as easy as I would have thought at least.

Essentially, you start an XML-RPC server in Java, and connect to it using a URScript command at runtime, passing the value of the runtime variable in. The Java server can then use that value in your methods. Bear with me here, it was a while ago that I did this, so I don’t really remember what/why I did it.

ScriptToJava class (this establishes the server that the URScript will pass information to):

package com.myCompany.myCAP;

import java.io.IOException;

import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.server.XmlRpcServerConfigImpl;
import org.apache.xmlrpc.webserver.WebServer;

public class ScriptToJava extends XmlRpcServer{
//public class ScriptToJava {
	private WebServer webServer;
	
	public ScriptToJava(int port) throws Exception {		
		webServer = new WebServer(port);
        XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();

        PropertyHandlerMapping phm = new PropertyHandlerMapping();
        phm.addHandler("method1", JavaScriptHandler.class);
        phm.addHandler("method2", JavaScriptHandler.class);
        phm.addHandler("method3", JavaScriptHandler.class);
        xmlRpcServer.setHandlerMapping(phm);

        XmlRpcServerConfigImpl config = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
        config.setEnabledForExtensions(true);
        config.setContentLengthOptional(false);
	}
	
	public void start() throws IOException {
        webServer.start();
    }

    public void stop() {
        webServer.shutdown();
    }
} 

I initialize this class in my activator with the following (you can use whatever port number you want, just make sure you use the same one everywhere):

//Start an XMLRPC server to be used from URScript
try {
	ScriptToJava myServer = new ScriptToJava(40406);
	myServer.start();
	System.out.println("XML_RPC server has started on port: 40406");
} catch (Exception e) {
	e.printStackTrace();
}

JavaScriptHandler class (this is what is being used in the “addHandler” method in the previous class):

package com.myCompany.myCAP;

public class JavaScriptHandler {
	
	public int saveLastCount(int input) throws ScriptToJavaException{
		java.awt.EventQueue.invokeLater(new Runnable() {
	        public void run() {
	        	undoRedoManager.recordChanges(() -> {
	    			model.set(last_variable_value, input);
	    		});
	        }
	    });
        return 0
    }
	
	public int method2Function(int input) throws ScriptToJavaException{
		System.out.println("Example method2 prints " + input);
		return 0;
	}
	
	public int method3Function(int input) throws ScriptToJavaException{
		System.out.println("Example method3 prints " + input);
		return 0;
	}
}

And finally the exception class being referenced above:

package com.myCompany.myCAP;

public class ScriptToJavaException extends Exception{
	private static final long serialVersionUID = 0L;

    public ScriptToJavaException(String message) {
        super(message);

    }
}

You should be able to add these 3 class files to your project, and rename a few things as necesary.

From the URScript side:
First you will need to create a variable and attach it to the server:

myServerVar= rpc_factory("xmlrpc", "http://127.0.0.1:40406/RPC2")

This allows us to do things like “myServerVar.method1.saveLastCount(current_count)” inside the URScript, and execute that method in java.

Finally, I think I added a dependency for the XMLRPC server:

<dependency>
	<groupId>org.apache.xmlrpc</groupId>
	<artifactId>xmlrpc-server</artifactId>
	<version>3.1.3</version>
</dependency>

Which I have embedded with the following line:

<Embed-Dependency>xmlrpc-server, servlet-api, xmlrpc-common, xmlrpc-client</Embed-Dependency>

No idea if that’s necessary, I can only guess that something wasn’t working, so I added that at some point.

And that should be everything (I think). I probably forgot something, but I’m sure back in the day I had just been Googling something like “xmlrpc java” so you could always try that too.

1 Like

Thank you very much for your knowledge. I will try this as soon as posible and update you if it works!

Thank you for your quickly responses and your experience!

Best regards