morse-simulator / morse

The Modular OpenRobots Simulation Engine
http://morse-simulator.github.io/
Other
353 stars 156 forks source link

Can't get a data stream in an external script using pymorse #712

Closed ajfisher closed 8 years ago

ajfisher commented 8 years ago

I am using the latest master branch and installed locally (OSX Yosemite, python 3.5.1, blender the same). I can render a default scene and I can control the robot in that space. Notably I can also do the following:

Where I'm having issues though is from an external python script, any time I try to call sim.robot.camera.get() I get an attribute error. This is consistent across every Component as well.

Minimal builder file to reproduce the issue:

from morse.builder import *

robot = RMax('robot')
robot.translate(15.0, 20.0, 10.0)  # Can translate() any component

pose = Pose()
pose.translate(z = 0.75)
pose.add_stream('socket')
robot.append(pose)

robot.add_default_interface('socket')

env = Environment('land-1/trees')
env.set_camera_location([6.0, 25.0, 10.0])
env.set_camera_rotation([1.5708, 0.0, -1.5708])  # 90 degrees= 1.5708 radians

Now, I create a python shell or a script and simply do this:

import pymorse
sim = pymorse.Morse()
data = sim.robot.pose.get()

And I get this as an error:

AttributeError: 'Component' object has no attribute 'get'

Sure enough, looking at the object there's no get method available:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_add_service', '_morse', 'close', 'fqn', 'get_configurations', 'get_local_data', 'get_properties', 'name', 'set_property']

But reviewing that the simulator things, it should be there:

[  102.290] [middleware.socket_request_manager] Sent back 0 SUCCESS {"environment": "land-1/trees", "robots": [{"name": "robot", "components": {"robot.pose": {"type": "Pose", "stream_interfaces": [["morse.middleware.socket_datastream.SocketDatastreamManager", "OUT"]], "service_interfaces": ["morse.middleware.socket_request_manager.SocketRequestManager"], "services": ["get_local_data", "get_properties", "get_configurations", "set_property"]}}, "type": "RMax"}]} to <socket.socket fd=20, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 4000), raddr=('127.0.0.1', 62283)>

So I'm not sure what's going on but I definitely can't get() the data stream, even though everything is saying that the data stream is there, the robot.pose object doesn't appear to believe it exists for some reason.

Any help would be gratefully received at this point as I've been hair pulling for a few days now. :(


adegroote commented 8 years ago

Can you also post the output of Morse from this simulation ? Thanks in advance

ajfisher commented 8 years ago

I wasn't sure how much you wanted of it so I chucked the whole lot of it in a gist here:

https://gist.github.com/ajfisher/23f4a1b066000fdf465f6af44dd15108

adegroote commented 8 years ago

It starts good, but you should also post the part after the initialization, when you launch your "pymorse" script. The configuration looks good. I don't see specific reason that it fails.

Can you add the following line at the beginning of your pymorse script and tell me the output you have ?

import logging

logger = logging.getLogger("pymorse")
logger.setLevel(logging.DEBUG)
ajfisher commented 8 years ago

Sure thing. Will be gone shortly so can give it a go then and post the results for you.

On Tue, 2 Aug 2016, 18:04 Arnaud Degroote notifications@github.com wrote:

It starts good, but you should also post the part after the initialization, when you launch your "pymorse" script. The configuration looks good. I don't see specific reason that it fails.

Can you add the following line at the beginning of your pymorse script and tell me the output you have ?

import logging

logger = logging.getLogger("pymorse") logger.setLevel(logging.DEBUG)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/morse-simulator/morse/issues/712#issuecomment-236832430, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHRo6JOMAuAo5UiUbiT_Xg0sofPmhQgks5qbvoMgaJpZM4JZhGw .

ajfisher commented 8 years ago

Okay - updated that gist. Full output log from the morse run and then exception + traceback from the python side.

Logging didn't appear to add much to the error messages though unfortunately.

https://gist.github.com/ajfisher/23f4a1b066000fdf465f6af44dd15108

ajfisher commented 8 years ago

Updated with better logging output.

ajfisher commented 8 years ago

Update from my side. I've gone through with pdb and watched what was going on. It looks like I may have 2 issues happening here though I'm not sure how related they are.

The first thing is that when I get this response back to pymorse for processing from the sim:

{'robots': [{'components': {'robot.pose': {'services': ['get_local_data', 'get_configurations', 'get_properties', 'set_property'], 'stream_interfaces': [['morse.middleware.socket_datastream.SocketDatastreamManager', 'OUT']], 'type': 'Pose', 'service_interfaces': ['morse.middleware.socket_request_manager.SocketRequestManager']}}, 'name': 'robot', 'type': 'RMax'}], 'environment': 'land-1/trees'}

And this gets parsed in initialisz_api() it is creating the components with _add_component() and it is expecting to see a stream object. As you can see in the robot.pose object in the JSON above there is no streams property however there is a stream_interfaces property.

Walking the code it appears this is largely a cosmetic check anyway because the port is determined with a call to get_stream_port() with the name of the component you're looking for - in this case "robot.pose" which will then return the port of my stream interface which is 60000.

From what I can gather the "stream" property should be "IN|OUT" so simply grabbing that from the stream_interfaces object gives me the required info and if I do that it passed to the Component constructor all fine.

Question Is the stream object not being supplied for some reason from Morse itself / why wouldn't that be the case when it clearly creates it?

So I can now "massage" my data in using a couple of small changes to the pymorse file and get the data I'm trying to get but that's not really ideal and I think it would be better to understand what's happening here.

Any further ideas.

adegroote commented 8 years ago

It looks like you have a mix of a pymorse associated to Morse 1.3 and Morse 1.4. pymorse reads properly 'stream_interface' since previous September (see commit https://github.com/morse-simulator/morse/commit/137e97f5456ea60e68854147334d7a6d10438402).

ajfisher commented 8 years ago

Ouch.... well that explains why everything is so confused.

So my installation of all of this happened on this weekend just gone with a straight git clone https://github.com/morse-simulator/morse followed by the make steps so I'm not sure how I ended up with an older version of pymorse....

And ideas on what I need to do to clean it up?

adegroote commented 8 years ago

Maybe you have an old installation somewhere else ?

What is the output of

python3 -c "import pymorse; import sys; print(sys.modules['pymorse'])"  

Does it match your installation directory or does it point elsewhere ?

ajfisher commented 8 years ago

This is the first and only time I've installed it so definitely only one version.

Looking at the version of pymorse that's in site-packages versus the one that is in github it's definitely different.

The only thing I can think of is I've somehow installed it using pip or something and it pulled an older version?? What's the right way to install pymorse from github as that isn't documented eg here: http://www.openrobots.org/morse/doc/1.3/user/installation.html

ajfisher commented 8 years ago

It's definitely in my site packages so only thing I can think is I went onto autopilot and did pip install pymorse and it pulled v1.2

I've nuked that and then from morse/bindings/pymorse/src/ done a pip install -e pymorse which has added the reference to that file.

I run:

python3 -c "import pymorse; import sys; print(sys.modules['pymorse'])"

And sure enough it's pointing to the github folder

Then I execute my demo code and voila it works as expected! No more bailing on the streams.

Sorry about that - definite user error on my part. Thanks for helping, I'd have never got that version issue through not being familiar enough with your code.

I can now drive a robot around in the morse and pass the data out to another script absolutely fine now though so success!

Closing this out as SOLVED.

adegroote commented 8 years ago

Normally, there is nothing to do, make install should install by default. We probably need to upgrade the version on pip side through. Thanks for the report anyway, and enjoy Morse.