RPyC

Once again, I strongly recommend that you use the VS Code workflow for your EV3 Python programming, which implies that I strongly recommend that you do not use RPyC.

The first nine minutes of this one hour YouTube video introduce the RPyC workflow. I put it first because I think it is the most interesting of the 13 possible EV3 python programming workflows that are discussed (the video was made before the much superior VS Code workflow was available). I look again at the RPyC workflow, in more detail, later in the same video.

What is RPyC and why should I use it?

According to Wikipedia, RPyC (pronounced are-pie-see), or Remote Python Call, is a 'python library for remote procedure calls (RPC), as well as distributed computing'. According to ev3dev.org, RPyC is a transparent python library for symmetrical remote procedure calls, clustering and distributed-computing. RPyC makes use of object-proxying, a technique that employs python’s dynamic nature, to overcome the physical boundaries between processes and computers, so that remote objects can be manipulated as if they were local. Maybe all of that means something to you - it doesn't mean much to me!

The way I see RPyC is that RPyC provides a neat and simple way of connecting your PC to your EV3 such that you can run your EV3 python scripts on the PC, with the PC and the EV3 communicating in such a way that the scripts seem to be running on the EV3. So, for example, I can run a python script on my computer and, via RPyC, the script can access modules such as ev3dev module which are located on the EV3. This should work with any python IDE on my computer, so I can run my scripts on my computer using the python IDE of my choice and the EV3 behaves as if the script is being run on the EV3. That to me, is the main reason to use RPyC, but there are many other advantages too. Once the RPyC has been set up as described on this page:  

Please note that if you follow the instructions on this page you are giving yourself the additional option of running your scripts on the PC - it is still possible to launch the scripts from the terminal or from Brickman, in which case RPyC will not be used and the scripts will run just as if they had not been modified for compatibility with RPyC.

Getting ready for a programming workflow based on using RPyC with your python IDE rather than using a terminal

Before you can use RPyC for your EV3 python programming you have to complete a few simple steps. Follow the instructions on this page CAREFULLY for a stress-free RPyC experience!

Here are the steps in more detail:

1. Install RPyC on your EV3 and on your computer

To use RPyC you must first install RPyC on both the EV3 and on the computer. See this page for help with that.

2. Prepare a file that you will use to launch the RPyC server on the EV3

That same page also tells you how to prepare a file rpyc_server.sh (it contains just two lines of text) which should be saved to your robot folder on the EV3 and made executable. Before running your RPyC-ready scripts on the computer (don't do that yet - you'll be doing that in step 6), you must start the RPyC server running on the EV3 by running the file rpyc_server.sh, preferably from Brickman. Theoretically, you could also launch the file from a terminal, using the command /bin/bash rpyc_server.sh  or perhaps ./rpyc_server.sh, but one of the great advantages of using RPyC is that it makes it possible for you to do day-to-day EV3 python programming without using the terminal, so that would be less appropriate. It takes about 30 seconds for the server to start up on the EV3 and you will know when it is ready because (if you started it from Brickman) the LCD will become clear, with just a little tiny text at the top. If you forget to start the server on the EV3 before running your script on the computer you will simply receive an error message.

Once you've started the server running on the EV3 we will learn later how to make Brickman visible again so that you will have the option of running you scripts either from your python IDE on the computer or from Brickman. There is no need to stop the server running at any time since scripts can be run from Brickman even while the server is still running on the EV3. If you absolutely want to stop the server running for some reason then:

3. Modify your scripts in certain ways

Your python script needs to have three special lines included before it can use RPyC, namely the first three lines of this script:

import rpyc

conn = rpyc.classic.connect('ev3dev') #host name or IP address of EV3

ev3 = conn.modules['ev3dev.ev3']      #import ev3dev.ev3 remotely

m = ev3.LargeMotor('outB')

m.run_timed(time_sp=1000, speed_sp=600)

The second line above establishes a connection (conn) to the ev3dev library on the EV3, and the following line is like the line    import ev3dev.ev3 as ev3   which you might use if you were not using RPyC.

The final two lines are, of course, to run a large motor on port B for 1 second. And this script is ready to run from your favorite python IDE on your computer provided you have followed all the instructions on this page - just press the run button!

The script above only works if it is run from the computer, and you may be assuming that the scripts you are working with are actually stored and edited on your desktop PC. But it is also possible to store the scripts on the EV3, which you will have to do if you want to be able to launch them from Brickman (or you could copy the scripts from the computer, but that's more cumbersome). To make it easy to save your scripts on the EV3 directly from your preferred python IDE on the computer, I suggest you install SFTP Net Drive Free on your Windows PC (I'm not sure of the procedure for Mac or Linux computers but it must be just as easy). Net Drive Free allows you to easily map the robot folder on the EV3 to a drive letter on the PC, such as Z:, so that when you save your script to the Z: drive you are actually saving it straight onto the EV3. When downloading Net Drive Free you will be asked to provide your name and email address but there is no activation-by-email mechanism.

Saving your RPyC-ready script to the EV3 means you can run your script from the computer, as previously described, or from Brickman on the EV3 (you also have the option of launching it from a terminal, such as PuTTY, but on this page we are aiming for a terminal-free workflow). But if you run your script from Brickman or from a terminal there is no need to use RPyC, so we should modify our script so that RPyC is used only if the script detects that the script is not running on the EV3, but somewhere else (on our computer). The following code can do that:

#!/usr/bin/env python3

import socket

hostname = socket.gethostname()

if hostname == 'ev3dev':

    # We are on the EV3, import required modules directly

    import ev3dev.ev3 as ev3

else:

    # We are somewhere else. Assume we are using RPyC:

    import rpyc

    conn = rpyc.classic.connect('ev3dev')

    ev3   = conn.modules['ev3dev.ev3']

m = ev3.LargeMotor('outB')

m.run_timed(time_sp=1000, speed_sp=600)

The second and third lines get the name of the host, which will be 'ev3dev' if the script is running on the EV3. In that case, we don't need to use RPyC so ev3dev.ev3 is imported in the usual way.

If the host name is NOT 'ev3dev' then we make an RPyC connection as previously explained.

Note that the highlighted line says import ev3dev.ev3 as ev3 and not from ev3dev.ev3 import *. You MUST use the former format if you want to use RPyC, and that means that elsewhere in your code, when creating a Largemotor() object, for example, you must use the form m = ev3.LargeMotor() and not m = LargeMotor().

Problem: this script is starting to look a bit long and ugly! Do we really have to start our script with all this code if we want to be able to run our script either on the computer, using RPyC, or on the EV3, NOT using RPyC? No! We can take that code and move it into a python file which will be imported by our scripts. For example, we could make a python file called import_module.py containing this code:

import socket

hostname = socket.gethostname()

if hostname == 'ev3dev':

    # We are on the EV3, import required modules directly

    import ev3dev.ev3   as ev3

    import ev3dev.fonts as fonts

    import PIL

else:

    # We are somewhere else. Assume we are using RPyC:

    import rpyc

    conn  = rpyc.classic.connect('ev3dev')

    ev3   = conn.modules['ev3dev.ev3']

    fonts = conn.modules['ev3dev.fonts']

    PIL   = conn.modules['PIL']

and then import the contents of that file into our motor file like this:

#!/usr/bin/env python3

from import_module import *

m = ev3.LargeMotor('outB')

m.run_timed(time_sp=1000, speed_sp=600)

In order for this to work, the file import_module.py should be in the same folder as the script that will be importing it. Note that since we want to be able to run this script from Brickman, we need to include that special first line called a 'shebang' so that the EV3 knows that it should open the script using the python3 interpreter. Note also that the yellow-highlighted line does not include the .py extension for the imported file. The green-highlighted lines are included even though they are not needed in the motor script because by including this code we have made a generic import_module.py file that can be used with ALL our python scripts.

Higher up this page I said that when using the RPyC workflow there is 'no need to learn or use any Linux commands when working in this way'. But aren't there certain Linux commands that are needed frequently in order for EV3 python scripts to run correctly? These are the Linux commands that are used most often when working with EV3 python:

We should not need the first two commands if we are using an IDE because the IDE should have buttons for running and stopping the script (if it does not stop by itself).

So is it really possible to do day-to-day EV3 python programming as described in the second paragraph without having to occasionally use a terminal to run the Linux commands listed above? I believe it IS possible to do this. Read on! But note that I said 'day-to-day' python programming - you will need to use a terminal to complete the one-time set up instructions on this page before you can begin working 'terminal free'.

The last two commands, for hiding or showing Brickman, are needed only for scripts that use the LCD screen, which is a minority of scripts. To hide Brickman from a terminal, you would execute this command:  sudo chvt 6. To show Brickman from a terminal, you would execute this command:  sudo chvt 1. As we want to achieve a workflow based on RPyC and a python IDE rather than on using a terminal, it's good to know that Linux commands can be included within our python scripts like this:

import os

os.system('sudo chvt 6')

but there is a problem here: sudo normally requires us to enter a password and it is difficult to make the script do this for us. Solution: remove the requirement that a password be entered for this command 'chvt' only. This can be done by following these instructions, inspired by this page:

robot ALL=(ALL) NOPASSWD: /bin/chvt

4. Prepare a file that you will use to mark python scripts as executable

My solution to mark python files as executable without using a terminal is to keep in my robot folder a file called make_executable.sh which contains the following code:

#!/bin/bash

find -name '*.py' -exec chmod -R +x {} \;

The first line is a 'shebang' that tells the EV3 to use Bash to run the file. Think of Bash as the command line that you see when you are using a terminal. The line in bold finds every file with the ending .py and executes the command chmod +x on those files to mark them as executable. The -R switch is to make the search 'recursive' so that the search happens not only in the current folder but also in all its subfolders.

Of course, the file make_executable.sh must itself to be made executable using a terminal before it can be run from Brickman, but once this has been done you may never again need to use a terminal to make a python script executable, just run make_executable.sh instead! On my EV3, which has about 100 python scripts in several folders, it takes about 10 seconds for the make_executable.sh script to make sure that every python script is marked as executable.

5. Prepare a file that you will use to make Brickman visible again after the RPyC server has been started on the EV3

One last step as you prepare to use RPyC... You would want to start the RPyC server on the EV3 by running the file rpyc_server.sh from Brickman (you don't want to start it with a terminal because we're trying to avoid using the terminal from now on and you can't start it from your python IDE because it's not a python file). But running that file will leave Brickman hidden, so we need a way to display Brickman again so that we can launch python files from Brickman (there is no problem launching python files from Brickman while the RPyC server is running on the brick). So make a python file called show_brickman.py with the following code:

#!/usr/bin/env python3

from import_module import *

os.system('sudo chvt 1')

Recall that we have removed the password requirement for running sudo chvt 1. Save the file to the robot folder and make it executable by running make_executable.sh from Brickman. If you think about it, the shebang (first line) in the above code is not helpful because the shebang is only used when you try to run scripts from Brickman, and if you had access to Brickman you wouldn't be running this script in the first place!

6. Begin EV3 Python programming using RPyC rather than the terminal

Congratulations! You should now be ready to have a great experience using RPyC and SFTP Net Drive Free (on Windows) and NOT needing to use a terminal any more for day-to-day EV3 python programming! Your Windows workflow from now on, except for those rare times when you may need to use a terminal, will be:

Official RPyC website and tutorial

The official RPyC website is at rpyc.readthedocs.org and a tutorial is available here but isn't really needed if you understand this page and frankly it is much more detailed than you need as a beginner.

Thanks

I warmly thank ev3dev core team member Denis Demidov for his help with RPyC.