On 07/03/2013 06:05 PM, Dr. Kevin Nickels wrote:
Folks,
 The python IR proxy doesn't seem to be returning data in an accessable format.

Background:
 I'm trying to get an epuck working with the python clients.
 I'm using player-3.0.2 with stage-3.2.2

What works:
In simulation, I follow Jenny Owen's lead and model the IR sensors as sonars.  All is well here.  (These versions don't support a simulated IR interface.)

For the real epuck, I took the GCTronic Demos (here) and replaced one demo with Renato Florentino Garcia's epuck player driver (from here).  This provides an IR interface.  I can view the results from the real epuck with playerv and all seems correct.

Issue:
My next problem is when I try to access the data with playerc.py (yes, my real code has more and error checking and etc...):
   c = playerc_client(...)
   s = playerc_ir(c,0)
   c.read()
   print s.data.ranges_count

This yields 8, matching the epuck.  However, looking at s.data.ranges, I see a SwigPyObject with the following fields:
s.data.ranges.__class__         s.data.ranges.__ne__
s.data.ranges.__cmp__           s.data.ranges.__new__
s.data.ranges.__delattr__       s.data.ranges.__oct__
s.data.ranges.__doc__           s.data.ranges.__reduce__
s.data.ranges.__eq__            s.data.ranges.__reduce_ex__
s.data.ranges.__format__        s.data.ranges.__repr__
s.data.ranges.__ge__            s.data.ranges.__setattr__
s.data.ranges.__getattribute__  s.data.ranges.__sizeof__
s.data.ranges.__gt__            s.data.ranges.__str__
s.data.ranges.__hash__          s.data.ranges.__subclasshook__
s.data.ranges.__hex__           s.data.ranges.acquire
s.data.ranges.__init__          s.data.ranges.append
s.data.ranges.__int__           s.data.ranges.disown
s.data.ranges.__le__            s.data.ranges.next
s.data.ranges.__long__          s.data.ranges.own
s.data.ranges.__lt__           

So any idea how I can get at the actual IR ranges?  This looks something like a linked list (append, next), but I can't figure out how to get at the data.

The C++ examples I've found just reference s.data.ranges[index], but that doesn't work with this structure.

Any pointers appreciated.
--kn

Hi Kevin,

Thanks for the detailed description of your problem.  I took a look at this tonight, the problem is with how playerc is storing the IR proxy's data internally.  Right now, if you look at playerc.h, you'll see that playerc_ir_t is just a collection of other structs (playerc_ir_data_t and playerc_ir_poses_t) from the IR interface.  You'll notice that other interfaces (e.g. playerc_ranger_t) don't re-use the data structs from their interfaces, and instead replicate the fields from the different interface messages right in the base class.

The problem is that when playerc is pre-processed for swig parsing, the pre-processing script doesn't descend into any of the sub-structures of the playerc_<interface>_t structures.  One of the more important parts of the swig preprocessing is replacing any array pointers with structs like "doubleArray" or "floatArray" which have swig translations into python arrays.  As a result, you can see the "data" structure and access the non-pointer elements of it, but you can't actually get in to the ranges array because swig doesn't know what to do with it.

To solve this issue, you'd have to change playerc_ir_t to not use the player_ir_data_t structure, and instead replicate those fields directly in the playerc_ir_t structure.  After doing that, you would also have to change the definition of playerc_ir_putmsg to do the correct translation between the player_ir_data_t struct and the playerc_ir_t struct.  From there you'd also probably have to edit the playerc++ wrapper as well to make sure that they don't try to use the data field of playerc_ir_t as well, as well as any other utilities that use the ir interface.  Changing this would break all consumers of the playerc ir interface; I would be willing to adopt this change in Player for version 3.1 (which will have an API/ABI version bump.)

Also worth mentioning is that there are python bindings for the playerc++ library, which aren't built by default (you'll have to turn them on in CMake.)  Have you tried to use the playerc++ python bindings?

Rich