Universal Robots Forum

Script inside the UR Caps to read registers

Hello,

I managed to get a value in my URCaps (that the user input) and write this value in the output register via a script inside the URCaps. (So I can read it via PLC.)

The problem is that I need to do a handshake with the PLC, therefore, the PLC will write in the input registers, and I need to access theses values inside my URCaps.

The code to write in the output registers I successfully implemented, and it works.

@Override
public void generateScript(ScriptWriter writer) {
	writer.appendLine("write_output_integer_register(0," + model.get(VALOR_VAR, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(1," + model.get(VALOR_VAR1, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(2," + model.get(VALOR_VAR2, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(3," + model.get(VALOR_VAR3, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(4," + model.get(VALOR_VAR4, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(5," + model.get(VALOR_VAR5, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(6," + model.get(VALOR_VAR6, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(7," + model.get(VALOR_VAR7, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(8," + model.get(VALOR_VAR8, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(9," + model.get(VALOR_VAR9, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(10," + model.get(VALOR_VAR10, 0d) + ")");
	writer.appendLine("write_output_integer_register(11," + model.get(VALOR_VAR11, 0d) + ")");
}

As this is a write only method, it is declared as a void, because I need no returns.

The problem I am facing now, is that I didn’t find a way to send the “read_input_integer_register”, get the value, and assign it to public variable. It seems that the ScriptWriter is only void. Is it correct? How is it done to read the input registers inside my URCaps?

Thank you.

Hello caue,

you can use the read register Methods as well in the script writer, but then should assign the return value to a variable of your choosing. Then you can process the value later on.

For example:

writer.appendLine("plcValueRegister11 = read_input_integer_register(11)");

If you want to access the value before the program is executed, you can read this values using the RTDE interface.

1 Like

Hi @sko ,

Thank you for your reply. I did the following in the NodeContribution:

public Boolean handShakePLC = false; //declaration of the variable and initialization as false

public Boolean generateScript1(ScriptWriter reader) {
reader.appendLine(“handShakePLC = read_input_boolean_register(0)”);
return handShakePLC;
}

So, in this way my Booleand handShakePLC is receiving correctly the input Boolean Register (0) ?

If so, one more thing that I need to do to complete my project, is that I can’t let the program tree in the Polyscope pass by my UR Cap if this handShakePLC variable isn’t set as true. (It’s like a wait for handShakePLC = true but inside the UR Cap, so I don’t need to insert it manually in the program tree).

Is that even possible?

Thank you very much.

Hi caue,

the approach you described would not work.
The genereateScript()-method inserts the Script code you put in the brackets of the appenline()-method in the correspondent program code at the location your program node is inserted in the robot program.

reader.appendline( " #this will be put in the script code of the robot program " ) ;

Your logic, as far as I understand it from you question, should be implemented fully in the generateScript()-Method:

public void generateScript1(ScriptWriter writer) {
    writer.appendLine(“handShakePLC = False”);
    writer.appendLine(“handShakePLC = read_input_boolean_register(0)”);
    writer.appendLine(“while( handShakePLC  == False ):”);  
    writer.appendLine(“    handShakePLC = read_input_boolean_register(0)”);
    writer.appendLine(“    sleep( 0.1 ) ”);
    writer.appendLine(“end”);
}

This could be one, simple way to solve your issue.

"The genereateScript()-method inserts the Script code you put in the brackets of the appenline()-method in the correspondent program code at the location your program node is inserted in the robot program."

I see what you mean, it makes totally sense now!!

I copied exactly the code you did, but it still passes the UR Cap even when the handShakePLC is false, it doesn’t get stuck in a loop waiting for it to become true. It doesn’t generate any error either, it just goes to the next step in the program tree.

(I manually put a wait for the input boolean register to become true, and it does stops. But not with the UR Cap.)

Do you have any idea why?

EDIT:

Making this script directly inside the UR it works, it waits in the script step until the sentence becomes true. But when written via UR Caps it doesn’t work.

You can take a look at the generated script code the *.script-file correspondent to your robot program.
Maybe by comparing the three (URCap, wait-function, direct script) different approaches you can spot the issue.

Hello, I managed to make it work, I don’t know why, but it doesn’t allow two blocks of script, it only worked when I put everything in just one script generator.

This does NOT work:

@Override
public void generateScript1(ScriptWriter writer) {
writer.appendLine(“handShakePLC = 0”);
writer.appendLine(“handShakePLC = read_output_integer_register(0)”);
writer.appendLine(“while(handShakePLC == 0):”);
writer.appendLine(“handShakePLC = read_output_integer_register(0)”);
writer.appendLine(“sleep(0.1)”);
writer.appendLine(“end”);
}

@Override
public void generateScript(ScriptWriter writer) {
	writer.appendLine("write_output_integer_register(0," + model.get(VALOR_VAR, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(1," + model.get(VALOR_VAR1, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(2," + model.get(VALOR_VAR2, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(3," + model.get(VALOR_VAR3, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(4," + model.get(VALOR_VAR4, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(5," + model.get(VALOR_VAR5, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(6," + model.get(VALOR_VAR6, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(7," + model.get(VALOR_VAR7, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(8," + model.get(VALOR_VAR8, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(9," + model.get(VALOR_VAR9, 0d) + ")"); 
	writer.appendLine("write_output_integer_register(10," + model.get(VALOR_VAR10, 0d) + ")");
	writer.appendLine("write_output_integer_register(11," + model.get(VALOR_VAR11, 0d) + ")");
}

This DOES work:

@Override
public void generateScript(ScriptWriter writer) {
writer.appendLine(“write_output_integer_register(0,” + model.get(VALOR_VAR, 0d) + “)”);
writer.appendLine(“write_output_integer_register(1,” + model.get(VALOR_VAR1, 0d) + “)”);
writer.appendLine(“write_output_integer_register(2,” + model.get(VALOR_VAR2, 0d) + “)”);
writer.appendLine(“write_output_integer_register(3,” + model.get(VALOR_VAR3, 0d) + “)”);
writer.appendLine(“write_output_integer_register(4,” + model.get(VALOR_VAR4, 0d) + “)”);
writer.appendLine(“write_output_integer_register(5,” + model.get(VALOR_VAR5, 0d) + “)”);
writer.appendLine(“write_output_integer_register(6,” + model.get(VALOR_VAR6, 0d) + “)”);
writer.appendLine(“write_output_integer_register(7,” + model.get(VALOR_VAR7, 0d) + “)”);
writer.appendLine(“write_output_integer_register(8,” + model.get(VALOR_VAR8, 0d) + “)”);
writer.appendLine(“write_output_integer_register(9,” + model.get(VALOR_VAR9, 0d) + “)”);
writer.appendLine(“write_output_integer_register(10,” + model.get(VALOR_VAR10, 0d) + “)”);
writer.appendLine(“write_output_integer_register(11,” + model.get(VALOR_VAR11, 0d) + “)”);
writer.appendLine(“handShakePLC = 0”);
writer.appendLine(“handShakePLC = read_output_integer_register(0)”);
writer.appendLine(“while(handShakePLC == 0):”);
writer.appendLine(“handShakePLC = read_output_integer_register(0)”);
writer.appendLine(“sleep(0.5)”);
writer.appendLine(“end”);
}

But anyway, thank you very much for your explanation as how the script works inside the UR!!

My only doubt, is that by this script, it works only inside the UR, but now, how do I get this value from the read_output_integer_register(0) and move it to a variable inside my Java Code. Is this possible??

1 Like

Hi,

as Stefan said, you have to implement the RTDE interface on the java layer to achieve this :wink:

Hi,

I took I look at the RTDE interface, the problem is that my project is in this situation:

Machine(Devicenet) <==>(Devicenet)PLC(EthernetIP) <==>(EthernetIP) UR5e.

I already managed to write values in the machine via the UR, by using that script mentioned above.
(UR==>PLC==>Machine).

Now, I only need to read a return from the PLC from only ONE input register.

I understand now that the method generateScript runs only inside the UR.
But, isn’t there any other method that generate a script but it’s able to “export” this value so I am able to read it in Java?

Do I really need to use the RTDE interface?