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:
there is no need to use an SSH (Secure Shield) connection. All RPyC requires is an IP connection
there is no need to use a terminal
there is no need to learn or use any Linux commands (except for a couple that can be incorporated into your python scripts)
the RPyC server is lightweight - it uses much fewer resources than running IPython notebook on EV3
Some robots may need much more computational power than what EV3 can give you. A notable example is the Rubik's cube solver: there is an algorithm that provides almost optimal solution (in terms of number of cube rotations), but it takes more RAM than is available on EV3. With RPYC, you could run the heavy-duty computations on your desktop.
In my experience, once the RPyC server has been started on the EV3, python scripts actually launch much faster running on the PC and using RPyC than they would if started from the terminal or from Brickman.
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!
install RPyC on your EV3 and on your computer
prepare a file that you will use to launch the RPyC server on the EV3, preferably by running the file from Brickman
modify your scripts in certain ways
prepare a file that you will use to mark python scripts as executable
prepare a file that you will use to make Brickman visible again after the RPyC server has been started on the EV3
before attempting to run your EV3 python scripts on your favorite python IDE on the computer, launch the RPyC server on the EV3 and show Brickman again.
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:
If the server was started from Brickman you should first hide Brickman by running the script hide_brickman.sh (see later) and then press the back button on the brick.
If you started the server from a terminal, stop the server with Ctrl-C.
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:
python3 scriptname.py to launch a python3 script
Ctrl-C to force the script to stop running, if necessary
chmod +x scriptname.py to mark the script as executable
sudo chvt 6 to give the script control over the LCD screen - if this is not done then Brickman will grab back control of the LCD screen, perhaps after a very short time
sudo chvt 1 to give control of the LCD screen back to Brickman after the script has finished running
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:
Type sudo visudo at the terminal and enter the password (maker) to open the sudo permissions (sudoers) file
Around line 25, you'll see this line: %sudo ALL=(ALL:ALL) ALL
Below that line, insert the following line, (assuming 'robot' is your username):
robot ALL=(ALL) NOPASSWD: /bin/chvt
Exit the editor (Ctrl+X if nano), typing 'y' when asked if you want to save the modified buffer and accepting the proposed file name.
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:
Start SFTP Net Drive Free and map the EV3's robot folder to a Windows drive letter
Start your favorite python IDE, such as Thonny
Use the EV3's Brickman interface to launch the RPyC server on the EV3 by running the file rpyc_server.sh. Know that it takes about 30 seconds for the server to start up.
The previous step will hide Brickman. Make Brickman visible again by opening the file show_brickman.py in your Python IDE and running that.
Open existing python files on the brick from your python IDE or by double-clicking them in Windows Explorer, assuming you have set up the association in the usual way so that python files open with your python IDE by default. Edit, save and run your files from within the IDE. You can also easily launch the files from within Brickman. Do NOT open your python files in the python IDE from a terminal emulator like MobaXTerm. If you do that then you can edit your scripts and save your changes but you can't run or debug. That's because you're really working with a temporary local copy of the script on the PC, so when you try to run the local copy of python in is used. To eliminate the risk of opening scripts in the IDE from a terminal emulator, simply don't have a terminal emulator open – the whole point of this page was to enable a workflow that uses an IDE and a mapping utility such as SFTP Net Drive Free and no longer requires the use of a terminal emulator.
If making a new python file on the the brick, the easiest way to do so may be to use the IDE. Once you have made a new python file, don't forget to make it executable by running the file make_executable.sh from Brickman. This will find ALL the python files in the robot folder and subfolders and check that they are all marked as executable, a process that might take a few seconds.
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.