Quickstart#
Instantiating#
The central object in flexsea is the Device class. For most use cases, this is the
only aspect of flexsea that you will need to interact with directly. You can import
it into your code like so:
from flexsea.device import Device
Typically, all you’ll need to do to create an instance of the object is:
device = Device(port=YOUR_PORT, firmwareVersion=YOUR_VERSION)
On Windows, YOUR_PORT will typically be something along the lines of COM3. You can
determine which port your device is on by navigating to the Device Manager -> Ports (COM & LPT).
On Linux (Ubuntu and Raspberry Pi), the port will typically be something along the lines of
/dev/ttyACM0. You can check by using ls /dev/ttyACM* before connecting the device’s USB
cable and then after connecting the device’s USB cable. The port will be the difference between
the two outputs.
The value of YOUR_VERSION should be either the full semantic version string of the
firmware that’s currently on your device or the major version of the firmware that’s
on your device, e.g., “10.5.0” or “10”.
To see what versions are available, you can do:
from flexsea.utilities.firmware import get_available_firmware_versions
get_available_firmware_versions()
Note
Firmware version 7.2.0 is the latest long-term support release. FASTER customers should not update beyond this version unless given explicit instruction to do so from Dephy.
See the api docs for more details.
Connecting and Streaming#
Once instantiated, you need to establish a connection between the computer and the device. This is done via the open method:
device.open()
Additionally, if you would like the device to send its data to the computer – an action called streaming – then you must invoke the start_streaming method:
device.start_streaming(frequency)
where frequency is the rate (in Hertz) at which the device will send data.
Note
The maximum supported frequency is 1000Hz (over USB). If you are streaming over bluetooth, the maximum is 100Hz.
Reading and Printing#
If you are streaming, you can get the most recent device data from the read method:
data = device.read()
Where data is a dictionary. The available fields depend on the type of device as well as the firmware version. If you have not read from the device in a while, you can get all of the data that’s currently in the device’s internal queue by using the allData keyword:
allData = device.read(allData=True)
In this case, the return value allData will be a list of dictionaries, one for each time stamp.
To conveniently display the most recent data:
device.print()
print takes an optional keyword argument called data, which should be a dictionary returned by read. This lets you display data that was read at some arbitrary point in the past.
Logging#
Logging is enabled by default, and the verbosity of the logs is controlled by the logLevel
argument in the Device constructor. The allowed values are integers [0,6], with 0
being the most verbose and 6 disabling logging.
There are two kinds of logs: debug logs and data logs.
Debug logs are saved in a directory called DebugLog in the directory from which
flexsea is being run. The files contained inside are generally only useful if you are
trying to troubleshoot an issue, as they contain information related to communication
procedures and motor command messages.
Data logs are saved in a directory called DataLog in the directory from which
flexsea is being run. The files contained inside are csv files with all of the data
streamed by the device to the computer during your run. If your session was long (or
streaming rate high) your data will be broken up into several different files in order
to prevent any one file from getting too large. Only the first file will have the
column headings.
Controlling the Motor#
The Device class has methods for controlling the motor current, position,
voltage, impedance, and gains. Additionally, there is a method for stopping the motor:
Note
The stop_motor method resets all of the gains to 0 as a safety precaution.
When setting the gains:
kp: The proportional gainki: The integral gainkd: The differential gaink: The stiffness gain for impedance controlb: The damping gain for impedance controlff: The feed-forward gain
Device State#
You can also introspect certain aspects of the device’s state, depending on the firmware version you’re running:
connected: Indicates whether or not the computer and the device are connectedstreaming: Indicates whether or not the device is sending dataname: The name of the type of the device, e.g., “actpack”side: Either “left” or “right”, if applicable;Noneotherwise. Requires firmware >= v10.0.0.uvlo: Used to both get and set the device’s UVLO in millivoltsgains: The currently set gainsutts: The currently set UTT valueshasHabs: Whether or not the current device has a habsolute encoder
Cleaning Up#
When finished commanding the device, it is good practice to call the close method:
device.close()
Additionally, when done streaming, you can call the stop_streaming method:
device.stop_streaming()
Note
stop_streaming is called automatically by close, and close is called automatically by the Device class’ destructor, but it’s still good practice to clean up manually.