Writing Native Python Services

Services: 

PythonProxy

Hardware: 

Ubuntu computer (only Linux is supported at this time)

​This is a tutorial on how to write MyRobotLab services in Native Python.

 

REQUIREMENTS

For now, limited Java experience is still required to create a proxy service, but this may change in the future.

Basic knowledge of Linux and virtualenv is required, Google those if needed

Knowledge of the Python programming language

 

Procedure

Firstly, install MRL as a dev environment, as explained in the Getting Started tutorial.

Next, build and run MRL and install all services (or just PythonProxy, your choice)

During the install procedure, a new folder is created in the MRL base directory called native-mrl-services, with a subdirectory called python. Open this subdirectory in a terminal and type the following:

$ source bin/activate

 

This will activate the virtualenv and allow access to the local pip and python binaries, as well as required libraries. You will need to do this everytime you wish to develop the service or add libraries.

From here, read this, specifically the Services API section, to learn how to write a new service in mrlpy.

Create a new file with the name of the service with the .py extension. For example: TestService.py

Now, open this file and copy the example service's content to the new file, changing ExampleService to the EXACT name of the file, minus the .py extension

Add any method declarations you want here, they are automatically visible to MRL

Put the service definition in the services subfolder of the native-mrl-services/python directory

Next, we need to create a proxy service to expose a Java API for the new service. Open Eclipse and find the service file called _TemplateProxy.java

Copy this file with the name of the new service, exactly the same as the service defintion created earlier, replacing .py with .java. Don't forget to change the class declaration to match!

Now, for each method you want to expose, create a new method with that signature (return type Object). In the body, write this line:

return exec("NAMEOFMETHOD", new Object[]{DATA});

 

Replacing NAMEOFMETHOD and DATA with the method name and parameters respectively, casting parameters to Object as needed.

If you want your service to be visible in the Runtime menu, change visible = false; to visible = true;

Now, rebuild MRL and test. You've just made your first native service!

To push changes, tell git to push the new source tree then go back to the terminal and reactivate the virtualenv.

Run this command:

$ pip freeze > build/requirements.txt && cp -R services/ build/ && mv build ../python-build && deactivate 

Now a new folder called python-build is created one level up containing the necessary files for a new installation. Delete the python folder after verifing the services you created and the updated requirements.txt is in the python-build folder (backup both requirements.txt and the ENTIRE services directory to another folder OUTSIDE of the native-mrl-services directory if you are concerned). The python folder cannot be moved or renamed without breaking the installation (a side-effect of using virtualenv). Rename python-build to python. Now cd .. to exit the native-mrl-services directory and run this:

$ zip native-mrl-services.zip native-mrl-services/

This will create a new zip file containing the new build info and services. Move this file to your repo git, under com.nativeServices/VERSION (replacing VERSION with the newest present in the hierarchy, replacing the zip already there but leaving the ivy.xml file). Now commit and push the repo with a message stating that a new service was added. Now, the next time PythonProxy is installed it will pull this new zip containing the new service. Yay!

GroG's picture

Thanks AutonomicPerfectionist

Thanks AutonomicPerfectionist !  This is a great post.  I'm excited to see your development. 
I'm working on distributed messaging (overlay-network) in mrl now, and hopefully it will complement your work - in that it will be very easy to get bi-direction messaging working with any mrl connected to the distributed overlay network.  When I finish that I hope to go through your instructions - we have Node & Go to do too ! :D

Mats's picture

PythonProxy

I tried to follw the instructions here, but I can't find PythonProxy as a service in MRL. 

Is it on a different branch ? I'm using the develop branch. Or

is it still WIP and only available on your local build ?

 

 

AutonomicPerfectionist's picture

Pull Request

Yeah, PythonProxy is not in the develop branch. I don't have push privileges, so I created a fork to push my commits to. There is a pull request to merge my changes into the develop branch. The dependency (com.nativeServices) pushed directly to the repo, so it should be there. No idea if MRL will extract it to the correct place, though. It should create a folder in the MRL base directory called native-mrl-services, but I haven't been able to test this yet.