As seen in the firmware section, it is possible to control RoboVero with a simple serial terminal application. However, for anything but the simplest of tasks, this can quickly become unwieldy. The solution is a language interface that allows RoboVero functions to be called from within a program. One such API is the RoboVero Python Client Library. Python has a comprehensive standard library and online documentation making it an accessible and powerful language for robotics applications.
Overo COM Host
Depending on your distribution and image you might need to install python and some modules. On Angstrom,
You also need to download the Python Client Library. Because git doesn't exist on Angstrom, you will need to maintain it yourself. You can mount the SD Card to copy the PCL over, or use cURL:
Note the RoboVero HubCommander Interface. For the Overo to see the RoboVero, you must disconnect the USB mini-B. SSH to your Overo to send commands.
The Python Client Library is available via github. If you don't already use git you will need to install it.
Now you can get the most up to date version of the library.
The repository will be stored in ~/robovero/python. Before moving on, let's make sure everything is up to date.
If you are using Mac, install git from here. Now you can get the most up to date version of the library.
Python should already be installed on your Mac. To get pyserial, download the archive from http://pypi.python.org/pypi/pyserial. Unpack the archive, enter the directory in Terminal and run
NOTE: The installation instructions for Windows are in progress. Visit the Question and Answer section if you need help installing on Windows. You may also need to update your firmware to get it to work.
Python also needs to be installed on your Windows computer. Get Python 2.7 from http://python.org/download/. After that, to get pyserial, download the archive from http://pypi.python.org/pypi/pyserial. Unpack the archive. Set your Environment Variables by following instructions http://docs.python.org/using/windows.html#excursus-setting-environment-variables. Enter the directory in Command Prompt and run
The easiest way to get started with the Python Client Library is to try some of the included examples. Make sure that your RoboVero is powered, USB is connected, and the device has been reset (see pitfalls).
This examples measures a voltage on AD0_0.
This example displays x, y, and z readings for the on-board accelerometer, compass, and gyro.
This example requires an RC servo connected to PWM1.
Update your Python Client Library to access the latest examples.
For the most part, you can call Python Client Library functions the same way as C Peripheral Driver functions - python will even forgive you if your function call is followed by a semi-colon. Some key differences are outlined below using the peripheral pin select as an example.
Additionally, unless you want to append each function call with the name of the module containing it, you need to import functions and types individually by name.
C enums are represented by classes in Python. The enumerators are class variables. Here is the declaration of a function that accepts an enumerated type as its sole argument.
And here is how it is used in python and C.
Structs in C are treated as classes in Python. The main differences are declaration and referencing.
You can use lists, tuples, strings, etc. to store data in memory on the machine where python is running. In certain cases you need to store an array of data in RoboVero memory. One such case is to use the function UART_SEND which expects a pointer to an array of data. Here is one of many ways this can be achieved in C.
The robovero.extras module contains a class called Array. The initialization functions takes the number of elements, width of each element, and initialization values (optional) as arguments. Values can be a string, list, or single value to copy to RoboVero memory. In case a single value is provided, it is used for each element in the array.
There is a documentation site for robovero python library at Robovero Python.
Python can be used for developing your robotics applications quickly and interactively. Follow these steps if you find yourself limited by USB latency.
These four functions are often called sequentially to enable PWM in counter mode on a given channel.
Step 1: Create a python function
Step 2: Port your function to C
Once you're satisfied with your new function, convert it to C and add it to extras.c
Remember to include any headers that you reference.Now comes the tricky part. For your function to be called over USB it must have accept a string representing the arguments and return an int. To get an idea of how this is done, it's best to look at the wrappers for the functions you are using. The following function definition can be found in src/wrap/_lpc17xx_pwm.c
Which is fairly similar to our new function.
Let's take a closer look. First, prepend the function name with an underscore as a reminder that the function is intended to be called by the USB interface only. The arguments and return type are mandatory.
Arguments are passed to the function in a string separated by spaces. This first variable declared below is used as a pointer to the individual arguments. The other variables are used to store the arguments.
Now the arguments are separated, converted from string to unsigned long, and then typecast. If an argument is missing the function returns 1.
And finally, call the functions
The return value is used to indicate the status of the operation. If your function needs to return data, it needs to be sent via USB. The following snippet is from _PWM_GetCaptureValue which wraps the library function PWM_GetCaptureValue and returns an unsigned int.
Step 3: Append the driver function table
Add this entry to the driver function table in src/table.c. The first parameter is the command that causes your function to be invoked. The second parameter is the pointer to your function.Now add the prototype to extras.h
Step 4: Replace the python function
Add this new function to extras.pyNow remove the old function declaration from your original source file and replace it with an import.
That's it! We've just reduced four USB function calls to one.
extras.c and extras.py contain more examples of this process.
If you absolutely must use interrupts, there is no need to ditch the Python Client Library for a pure C firmware implementation. Simply write and test your interrupt service routine - you might be able to do so in python before porting to C - and then add it to the vector table in startup.c. Now, you can enable the interrupt through your python application and expect it to be handled with minimal latency.
Here are some hangups to watch out for when developing with RoboVero.
> There is currently no mechanism to synchronize firmware and software versions. If an example isn't working for you, it is possible that it was written for a more recent revision than that which shipped with your RoboVero. Update your firmware to the most recent version.
> When you first connect to RoboVero it asks you to press enter to begin. This is used to detect the line termination that your host machine is using - whether it be an Overo COM, desktop PC, etc. It is possible that PCL sends different line terminators than your favorite serial application (Kermit, Minicom, etc.). If such is the case, you will have to perform a hard reset when switching from Kermit to your program or vice-versa.