Updating Toolbar warning light with robotstate freezes polyscope

I have developed a URCap that implements a toolbar, this toolbar includes a digital warning light that changes the color of a panel according to the robot state.

The problem is that when the responsible part of the toolbarContribution is included after a few seconds with the toolbar open, polyscope sort of freezes. It is still possible to use most buttons, go into settings, and export logs but the robot can’t be turned off or the robot program stopped. The robot program also just stops at whatever step the “crash” happened.

Would appreciate any ideas or solutions :slight_smile:

Here is the relevant Code:

stateTimer = new Timer(5000, new ActionListener() {
	        public void actionPerformed(ActionEvent evt) {
	            EventQueue.invokeLater(new Runnable() {
	                public void run() {
	                    try {
	                        int robotState = exporter.exportIntegerFromURScript(readSignal, "state");
	                        System.out.println(robotState);
	                        switch (robotState) {
	                            case 0:
	                            case 1:
	                            case 3:
	                                warningLightPanel.setBackground(Color.RED);
	                                break;
	                            case 2:
	                            case 5:
	                            case 6:
	                                warningLightPanel.setBackground(Color.YELLOW);
	                                break;
	                            case 4:
	                            case 7:
	                                warningLightPanel.setBackground(Color.GREEN);
	                                break;
	                            default:
	                                // Handle unexpected state
	                                break;
	                        }
	                    } catch (Exception e) {
	                        e.printStackTrace();
	                    }
	                    frame.repaint();
	                }
	            });
	        }
	    });
	    stateTimer.start();

And the exporter code:

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.ServerSocket;

import java.net.Socket;



public class ScriptExporter {



	private final String SEND_IP;

	

	private String RETURN_IP;

	private int RETURN_PORT = 5500;

	

	private final String RETURN_SOCKETNAME = "\"EXPORT_SOCKET\"";

	

	/**

	 * Default constructor

	 * Sets transmission and return IP to localhost (127.0.0.1)

	 * Use this if on the same platform as URControl

	 */

	public ScriptExporter() {

		this.SEND_IP = "127.0.0.1";

		this.RETURN_IP = this.SEND_IP;

	}

	

	/**

	 * Constructor allowing a different robot IP than localhost

	 * @param Robot_IP the IP address of the robot

	 */

	public ScriptExporter(String Robot_IP) {

		this.SEND_IP = Robot_IP;

		this.RETURN_IP = this.SEND_IP;

	}

	

	/**

	 * Change the port which the data is returned to. 

	 * Default is 5500. Change is this port is occupied. 

	 * @param port The new port used to return data

	 */

	public void setReturnPort(int port) {

		this.RETURN_PORT = port;

	}

	

	/**

	 * Change the IP address which the data is returned to. 

	 * By default, the return IP and the transmission IP is the same. 

	 * @param Return_IP The IP address of this application

	 */

	public void setReturnIP(String Return_IP) {

		this.RETURN_IP = Return_IP;

	}

	

	/**

	 * When called, the ScriptCommand will be sent to the robot as a Secondary Program. 

	 * The variable with variable_name will be sent back, and will be returned. 

	 * User should ensure, that the script 

	 *    a) does not take physical time 

	 *    b) the variable variable_name is defined

	 *    c) the variable can be casted to int

	 * @param command The script command to send

	 * @param variable_name The name of the variable to return from the ScriptCommand

	 * @return The resulting value of the variable, as an integer

	 */

	public int exportIntegerFromURScript(ScriptCommand command, String variable_name) {

		ScriptCommand newCommand = buildScriptCommandToExport(command, variable_name);

		String reply = readValueFromRobot(newCommand);

		

		int integerValue = Integer.parseInt(reply);

		

		return integerValue;

	}

	

	/**

	 * When called, the ScriptCommand will be sent to the robot as a Secondary Program. 

	 * The variable with variable_name will be sent back, and will be returned. 

	 * User should ensure, that the script 

	 *    a) does not take physical time 

	 *    b) the variable variable_name is defined

	 * @param command The script command to send

	 * @param variable_name The name of the variable to return from the ScriptCommand

	 * @return The resulting value of the variable, as String

	 */

	public String exportStringFromURScript(ScriptCommand command, String variable_name) {

		ScriptCommand newCommand = buildScriptCommandToExport(command, variable_name);

		String reply = readValueFromRobot(newCommand);

		

		return reply;

	}

	

	private ScriptCommand buildScriptCommandToExport(ScriptCommand command, String variable_name) {

		// Change to secondary program

		command.setAsSecondaryProgram();

		

		command.appendLine("socket_open(\""+RETURN_IP+"\","+RETURN_PORT+","+RETURN_SOCKETNAME+")");

		

		command.appendLine("socket_send_string("+variable_name+","+RETURN_SOCKETNAME+")");

		command.appendLine("socket_send_byte(13,"+RETURN_SOCKETNAME+")");	// CR

		command.appendLine("socket_send_byte(10,"+RETURN_SOCKETNAME+")");	// LF

		

		command.appendLine("socket_close("+RETURN_SOCKETNAME+")");

		

		return command;

	}

	

	private String readValueFromRobot(ScriptCommand commandWithReturn) {

		String input = "";

		try{

			// Create return socket

			ServerSocket server = new ServerSocket(RETURN_PORT);

			

			ScriptSender sender = new ScriptSender(SEND_IP);

			sender.sendScriptCommand(commandWithReturn);

			

			System.out.println("Trying to accpet");

			Socket returnSocket = server.accept();

			System.out.println("Accepted");

			

			

			BufferedReader readerFromURScript = new BufferedReader(new InputStreamReader(returnSocket.getInputStream()));

			input = readerFromURScript.readLine();

			

			// Housekeeping

			readerFromURScript.close();

			returnSocket.close();

			server.close();

		} 

		catch (IOException e){

			System.out.println(e);

		}

		return input;

	}

	

}```

Making calls to the script exporter takes a lot of time. Doing so rapidly and consistently will cause the UI to hang BADLY. Making calls to it once every 5 seconds like you’re doing may very well just be too fast. Just try changing the time to a lot longer as a test to see if that’s the problem.

Hi @Fred,

what type of variable is “state” and where did you create your ScriptCommand “readSignal”.

Regarding your “crash” and line: System.out-println(robotState):
Do you manage to get a output in the console here?

Thx.