Toolbox

Data Recorder

class epicallypowerful.toolbox.DataRecorder(file: str, headers: list, delimiter: str = ',', overwrite: bool = False, time_as_relative: bool = True, buffer_limit: int = 200, verbose: bool = False)

A class for recording data to a delimited text file (csv, tsv, etc.). This class records data to a buffer (defined by the buffer_limit argument) before writing to the file in a separate thread. If you want to ensure data is written to the file as quickly as possible, use 1 for the buffer limit. By default the data recorder will record a time column, which is either relative to the start of recording or the device time. The presence of files matching the provided file path will be checked upon initialization, and if a file already exists a new file will be created with an incremented index unless overwrite is set to True.

Example

from epicallypowerful.toolbox import DataRecorder
recorder = DataRecorder('test_file.csv', ['sensor_1', 'sensor_2'], buffer_limit=100)
for i in range(1000):
    recorder.save([i, i*2]) # Saves a new line with the current time, i, and i*2
recorder.finalize() # Ensures all data is written to the file and closes the file
Parameters:
  • file (str) – The file path of the file to be saved. If the file already exists, a new file will be created with an incremented index.

  • headers (list) – A list of strings that will be used as the header for the file.

  • delimiter (str, optional) – Delimiter type to use. This is almost always ‘,’. Defaults to ‘,’.

  • overwrite (bool, optional) – Whether to overwrite a file with the same name as the provided file path if the file already exists. Defaults to False.

  • time_as_relative (bool, optional) – Whether the time recorded in the default time column should be relative to the first recording or device time. Defaults to True.

  • buffer_limit (int, optional) – The number of lines to add before writing to the file. if an error occurs during operation, it is likley that this many lines will be lost Passing None will not save any data to disk until finalize() is called. Defaults to 200.

  • verbose (bool, optional) – Whether to print out information about the file being created and saved to. Defaults to False.

Raises:
  • TypeError – Raises if the headers are not a valid list of strings.

  • ValueError – Raises if the delimiter is not a valid delimiter.

save(input_data: list)

Saves the provided list as a new line in the text file. Data in list will be seperated by the delimiter specifed when the DataRecorder is created.

Parameters:

input_data (list) – the input data to be saved as a list of values

finalize()

Closes the file handle and ensures all data is written to the file.

Clocking

class epicallypowerful.toolbox.LoopTimer(operating_rate, time_step_error_tolerance=0.1, verbose=False)

Class for creating a simple timed loop manager. This object will attempt to enforce a set frequency when used in a looped script. NOTE: this frequency cannot be guaranteed, and the actual frequency should be recorded if this is important for your application. Please see the benchmarks for expected maximum performance.

Example

from epicpower.toolbox.clocking import LoopTimer
looper = LoopTimer(operating_rate=200)

while True:
    if looper.continue_loop():
        # do something approximately every 5ms
        pass
Parameters:
  • operating_rate (int) – Desired operating frequency (in Hz)

  • time_step_error_tolerance (float, optional) – Tolerance for time step error, as a proporiton of the time step. i.e. 0.01 = 1% error. Defaults to 0.05.

continue_loop()

Determines when loop should continue based on current time and operating rate

Command Line Tools

Epically Powerful also includes a few cli tools to quickly test your system and get up and going.

Install MSCL dependencies for MicroStrain IMUs

Install MSCL Python package

ep-install-mscl [-h] [--dir DIR] [--to-env]

ep-install-mscl options

  • -h, --help - show this help message and exit

  • --dir DIR, -d DIR - Directory to install MSCL Python package. This will copy the package from the install directory to the specified directory (default: None)

  • --to-env, -E - Install MSCL Python package to the current Python environment as well as the system-wide Python environment. This is useful if you want to use the MSCL Python package in a virtual environment or a specific Python environment.

Collect MicroStrain IMU Data

Collect MicroStrain IMU data

ep-collect-imu-data [-h] --imu-serial-id IMU_SERIAL_ID [IMU_SERIAL_ID ...] [--output OUTPUT]
                    [--duration DURATION]
                    [--channels {acc,gyro,mag,quat,eul} [{acc,gyro,mag,quat,eul} ...]]
                    [--remote-sync-channel REMOTE_SYNC_CHANNEL]

ep-collect-imu-data options

  • -h, --help - show this help message and exit

  • --imu-serial-id IMU_SERIAL_ID, -id IMU_SERIAL_ID - IMU serial ID multiple can be specified (default: None)

  • --output OUTPUT, -o OUTPUT - Output file (default: output.csv)

  • --duration DURATION, -d DURATION - Duration in seconds (default: 30)

  • --channels CHANNELS, -c CHANNELS - Types of data to collect (default: ['acc', 'gyro'])

  • --remote-sync-channel REMOTE_SYNC_CHANNEL, -r REMOTE_SYNC_CHANNEL - GPIO pins to use for remote sync channels. Use this argument multiple times to specify multiple channels (default: None)

Visualize Dummy Data

Run dummy visualizer

ep-dummy-viz [-h] --ip-address IP_ADDRESS --port PORT

ep-dummy-viz options

  • -h, --help - show this help message and exit

  • --ip-address IP_ADDRESS, -ip IP_ADDRESS - UDP server IP address (default: None)

  • --port PORT, -p PORT - UDP server port (default: 5556)

Stream MicroStrain IMU Data

Stream MicroStrain IMU data

ep-stream-microstrain-imu [-h] --imu-serial-id IMU_SERIAL_ID [IMU_SERIAL_ID ...]
                          [--rate RATE]

ep-stream-microstrain-imu options

  • -h, --help - show this help message and exit

  • --imu-serial-id IMU_SERIAL_ID, -id IMU_SERIAL_ID - IMU serial ID (multiple can be specified and separated by comma) (default: None)

  • --rate RATE, -r RATE - Operating frequency [Hz] (default: 200)

Stream MPU9250 IMU Data

Stream MPU9250 IMU data

ep-stream-mpu9250-imu [-h] [--rate RATE] [--i2c-bus I2C_BUS] [--channel CHANNEL]
                      [--address ADDRESS]

ep-stream-mpu9250-imu options

  • -h, --help - show this help message and exit

  • --rate RATE, -r RATE - Operating frequency [Hz]. Defaults to 250 Hz (default: 250)

  • --i2c-bus I2C_BUS - Which I2C bus the sensor is on (e.g., –i2c-bus 7). Defaults to 7 for NVIDIA Jetson Orin Nano or 1 for Raspberry Pi (default: None)

  • --channel CHANNEL - (If using multiplexer) channel sensor is on (e.g., –channel 1). Defaults to -1 (no multiplexer) (default: -1)

  • --address ADDRESS - I2C address of MPU9250 sensor (e.g., –address 68). Defaults to 68 (default: 68)

Stream Actuator Data

Stream actuator data

ep-stream-actuator [-h] [--rate RATE] --actuator-type ACTUATOR_TYPE --actuator-id ACTUATOR_ID

ep-stream-actuator options

  • -h, --help - show this help message and exit

  • --rate RATE, -r RATE - Operating frequency [Hz] (default: 200)

  • --actuator-type ACTUATOR_TYPE, -at ACTUATOR_TYPE - Actuator type (see actuation.motor_data for possible types) (default: None)

  • --actuator-id ACTUATOR_ID, -ai ACTUATOR_ID - Actuator ID (CAN ID) (default: None)

Impedance Control Example

Run impedance controller on an actuator

ep-sample-impedance-ctrl [-h] [--rate RATE] --actuator-type ACTUATOR_TYPE --actuator-id
                         ACTUATOR_ID

ep-sample-impedance-ctrl options

  • -h, --help - show this help message and exit

  • --rate RATE, -r RATE - Operating frequency [Hz] (default: 200)

  • --actuator-type ACTUATOR_TYPE, -at ACTUATOR_TYPE - Actuator type (see actuation.motor_data for possible types) (default: None)

  • --actuator-id ACTUATOR_ID, -ai ACTUATOR_ID - Actuator ID (CAN ID) (default: None)

Position Control Example

Run impedance-based position control on an actuator

ep-sample-position-ctrl [-h] [--rate RATE] --actuator-type ACTUATOR_TYPE --actuator-id
                        ACTUATOR_ID

ep-sample-position-ctrl options

  • -h, --help - show this help message and exit

  • --rate RATE, -r RATE - Operating frequency [Hz] (default: 200)

  • --actuator-type ACTUATOR_TYPE, -at ACTUATOR_TYPE - Actuator type (see actuation.motor_data for possible types) (default: None)

  • --actuator-id ACTUATOR_ID, -ai ACTUATOR_ID - Actuator ID (CAN ID) (default: None)

Position Control with Visualization

Run impedance-based position control on an actuator with visualization

ep-sample-actuator-viz [-h] [--rate RATE] --actuator-type ACTUATOR_TYPE --actuator-id
                       ACTUATOR_ID --ip-address IP_ADDRESS --port PORT

ep-sample-actuator-viz options

  • -h, --help - show this help message and exit

  • --rate RATE, -r RATE - Operating frequency [Hz] (default: 200)

  • --actuator-type ACTUATOR_TYPE, -at ACTUATOR_TYPE - Actuator type (see actuation.motor_data for possible types) (default: None)

  • --actuator-id ACTUATOR_ID, -ai ACTUATOR_ID - Actuator ID (CAN ID) (default: None)

  • --ip-address IP_ADDRESS, -ip IP_ADDRESS - UDP server IP address (default: None)

  • --port PORT, -p PORT - UDP server port (default: 5556)

IMU Gyroscope Controled Actuator Position

Run actuator with IMU as controller input

ep-sample-imu-ctrl [-h] --imu-serial-id IMU_SERIAL_ID [IMU_SERIAL_ID ...]
                   [--rate RATE [RATE ...]] --actuator-type ACTUATOR_TYPE --actuator-id
                   ACTUATOR_ID

ep-sample-imu-ctrl options

  • -h, --help - show this help message and exit

  • --imu-serial-id IMU_SERIAL_ID, -id IMU_SERIAL_ID - IMU serial ID (multiple can be specified) (default: None)

  • --rate RATE, -r RATE - Operating frequency [Hz] (default: 200)

  • --actuator-type ACTUATOR_TYPE, -at ACTUATOR_TYPE - Actuator type (see actuation.motor_data for possible types) (default: None)

  • --actuator-id ACTUATOR_ID, -ai ACTUATOR_ID - Actuator ID (CAN ID) (default: None)