Xml - rpc python to java

Hello all,

I am trying to extract values from the controller box by reading them with modbus communication. In it I am processing an xml-rpc server that from the python script needs to send something to a java xml-rpc client. In the ProgramNodeContribution, when clicking a button, it should take over these values.

I used part of the myDaemon example for this, but it doesn’t work and I can’t find the error.
This is my code:

python xml rpc server - The modbus in python has been tested and works

java xml rpc client - this is largely taken from the myDaemon example

contribution variables

Contribution button - getting the values
When I look in the console I then get the message:
“IT DOESN’T WORK” (from the red block in the picture)

Is there anyone who can help me with this?:blush:

yours sincerely,
Zoe

Doing a little more debugging might help narrow the cause. For example, if you’re hitting the red block of code there, and seeing “IT DOESN’T WORK” that must mean an exception was thrown when you called the “getWaypoints()” function. So the problem lies in there, would be my guess.

Looking at that, we have 2 potential points of failure: the .execute() with your store_waypoints function, or the processString() function. Try putting some more System.outs in between these calls and see if it runs. For example, if you put a println after the .execute() but before the processString() and it DOESN’T run, then your problem is in the client.execute(Store_Waypoints) bit. If it DOES run, then your problem is in the processString() function.

It might also help to post your code for the store_waypoints function. This is the one written in Python I assume? You may be encountering some sort of typing error, where Java is looking for an ArrayList of Strings, but Python is returning ints or doubles or whatever. Just a thought.

2 Likes

Hi, can mydaemon sample can be running on your environment?
If it can’t be running, please check the below.

I cannot start daemon (XMLRPCmath) - URCap Development - Universal Robots Forum (universal-robots.com)

1 Like

You’ve killed two birds with one stone.

It was indeed Integers[ ] instead of Strings and the problem seems to be in the processString. I changed this to Integer and Integer[ ] and neither solution seems to work. (Of course I changed the contribution as well.)

python

java xml-rpc

I think I understand what the processString function does, but I don’t understand how to convert the operation to reading data from an Integer arrayList instead of from a String.

Sorry if this is a simple question, I have yet to learn to be a bit more self-sufficient in terms of finding and fixing bugs.

So the processString function looks like all it’s doing is checking that the generic “object” returned from the function is of type integer[ ]. If it is, it casts it to an integer array (by putting the (Integer[ ]) part in front of response) and then returns this. So you’re still getting the else statement, which means the result of client.execute() IS NOT of type Integer[ ].

Looking at your python code, you need to determine what data type “pose” is, as this is what is being returned. In Java, you’ve typed it as “Object” which is fine, but won’t get you an explicit type like String, Int, Double, etc. It might need to be this way since Java doesn’t really know what Python is going to return. This is why you’re checking the type later with processString.

My guess would be Python is returning either a double, or a list of doubles (double[ ]). I’m just kinda assuming this because a robot pose would normally be an array of 6 doubles. So either find out what the data type is in Python, or just shotgun approach it in Java by putting a bunch of if()s checking for various data types. if(instance of String), if(instance of int), if(instance of double) etc and see if any of them turn up a result.

I had done a similar test with our CAP a while back, so I just dug this up. This is the Python function:
image

It’s REALLY basic, all it does is add 5 to whatever value you pass it. But you’ll notice I use int(value) to force it to be an int. This way I know Python is returning an int.

So in Java:

image

I can check purely for if it’s an instance of Integer, and if it is, I type cast the result to an int (that way Java knows what it is from now on and I can perform integer operations on it).

Hello @eric.feldmann,

Sorry for the late response. I found out that my network was not good. Passing a single variable as a String and an Int is going well now. To make sure I am working with an Int I created an array of int’s to test. But passing an array still doesn’t work.

I tried .getClass().isArray(), which returns true, so it should be an array.

I have tried it with all possible variable types with instanceOf and the only one that seems to work is Object. From that I get an @ value that I can’t do anything with (I think),

Then of course when I want to put it into an Integer ArrayList I get an error message.

So I expect that it is also an Object that I get forwarded from the Python script. I found how to convert it to an Integer, but because (I think) the value is weird, I can’t use this.

What should I do to convert the @… to just an array of values.

Thanks a lot for your help!

Regards Zoë

Nice debugging! I just did a quick search to verify, but you cannot do a simple cast of Object to Int.

Here’s the stack overflow link: types - How to cast Object[] to int[] java? - Stack Overflow

A little further down in that page, someone talks about various methods for unboxing the object. Basically, the type Int does not extend Object, which means the compiler doesn’t know how it should convert it. As humans, you and I can say “it’s so easy! Just take each number in the object array and stick it into an int array!” Soooo that’s exactly what you have to tell the compiler!

// Using cast to specific type and auto-unboxing (object cast)
int[] arr1 = new int[A1.length];
for (int i = 0; i < A1.length; i++)
    arr1[i] = (Integer)A1[i];

Here we’re saying: Make a new array that is as large as the Object array. Then use a for() loop to iterate through that object, grab each ELEMENT, cast it to an Integer, and store it back to our new int array. We are providing the compile an explicit order of operations so it can’t just throw its hands in the air and give up. The compiler has no problem casting each element inside the object array to an int, it just doesn’t know how to convert the whole array in one go. Please give this a shot and see if it solves your error.

@eric.feldmann

It worked! I used the forloop from your comment in combination with an @Override toString method

Thanks you so much for your help again!

Regards Zoë