2

I am working on a robotics project with my lab. (Github) Most of the main components are done and documented. The setup is as follows:

  • We run opstn on the base station. It has a server used to communicate controller position to the robot.
  • We run rpi on a raspberry pi running on the robot. The two communicate via wifi and have a static address. The raspberry pi has a client program which requests the controller positions when it has time, decides what to run the motor.
  • The raspberry pi communicates with an mbed via USB to allow for hardware PWM.
  • The raspberry pi will also be working with I2C devices for monitoring data, and communicating it back to the base station for processing. This will eventually be run as a separate server process, and the base station will have a client process communicating with it.
  • The base station might need to have a client module to interpret the device data, running as a separate process.

The code does work, but we have to run it in a somewhat longwinded way:

  • On the base station, cd into kaginawa and python -m opstn, running opstn/__main__.py
  • SSH into the raspberry pi, cd into kaginawa and python -m rpi, running rpi/__main__.py

I was wondering how to properly launch submodules. For the rpi/__main__.py, I was thinking of providing two functions (the motor-controlling client and the device server) in __main__.py, and use multiprocessing to run them. Experiments seem to indicate that this would work.

What I want to do, though, is zip my directory into an executable, and then simply ./start_robot. This is what the Makefile does, and it works well. However, whatever I try, I seem to be unable to start opstn at all. And I will also need to work with the SSH too, since I will need to launch rpi with sudo. I can probably do that with paramiko using this reply.

If it is possible, I am thinking of using os.uname()[1] to check if it is on the raspberry pi and launch rpi, and opstn otherwise.

tl;dr How do you launch submodules that contain a __main__.py from the root __main__.py of a python package?

Community
  • 1
  • 1
Jean Nassar
  • 555
  • 1
  • 5
  • 13
  • unrelated: `os.uname()[1]` hack might make things confusing. Less opaque hack is to choose what to run based on the program name (the same runnable zip but different names appropriate for the task). Or better: generate individual scripts (see [setuptools entry-points](https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation)). – jfs Jan 16 '15 at 19:50

1 Answers1

1

The toplevel directory in the project should not be a Python package. It could be a directory with setup.py instead.

You shouldn't cd inside Python package. Put your zip somewhere in PYTHONPATH (check by print(sys.path)) and use absolute names to run submodules e.g., run:

$ python -m kaginawa.opstn

to run kaginawa/opstn/__main__.py script or run:

$ python -m kaginawa.rpi

to run kaginawa/rpi/__main__.py.

If you want to choose what to run at runtime then you could call kaginawa.opstn.main() or kaginawa.rpi.main() functions in kaginawa/__main__.py. And run it:

$ python -mkaginawa

You could run the zip directly.

To simplify including dependencies, you could use PyInstaller, cx_Freeze to bundle your code.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Thank you! I can't test it for another week or so, but I think calling `opstn.main()` and `rpi.main()` from within `kaginawa.__main__.py` would work, and is exactly what I want to do. – Jean Nassar Jan 16 '15 at 19:38