4. About the API Functionalities
4.1. Creating Connections and Streaming Data
Serial connection between the driver and the eteeDongle is established by calling the connect() function. This function automatically detects the COM port numbers of available eteeDongles through a VID filtering system and creates a connection to the first instance. Connection to specific ports can also be established by calling the connect_port() function instead; however, it is recommended to use the default connect() function.
The start_data() function sends a serial command instructing the eteeControllers to start streaming sensor data.
The run() functions starts a data loop in a separate thread. The data loop reads serial data, parses it and stores it in an internal buffer. The data loop also listens to serial and data events and manages event callback functions.
1etee = EteeController()
2etee.connect()
3etee.start_data()
4etee.run()
To stop the etee driver, run the stop() function. To command the eteeControllers to stop streaming data, call the stop_data() function. To close the connection between the eteeDongle and the eteeControllers, run the disconnect() function.
1etee.stop()
2etee.stop_data()
3etee.disconnect()
4.2. Retrieving Device Inputs
There are two ways to retrieve data from the eteeControllers, either using data getter functions or through event-based programming.
4.2.1. Data Getters Functions
Once the eteeController data stream is opened and the data loop is running, etee data is accessible through two methods: data getters and event-based methods.
When called, data getter functions retrieve the last data available in the internal buffer.
There are general-use data getters and specific-use data getters. For the general-use getters, the keys for the data and/or device to be retrieved need to be passed as arguments. In the case of the specific-use ones, these data getter functions retrieve specific tactile, gestures, IMU or device state values.
1# General-use data getters
2right_index_pull = etee.get_data("right", "index_pull") # Option 1: get_data(dev, w)
3right_index_pull = etee.get_right("index_pull") # Option 2: get_right(w) or get_left(w)
4
5# Specific-use data getters
6right_index_pull = etee.get_index_pull("right")
For the full list of input keys for the general-use getters, see 5.2. Data Packet Structure.
For the full list of available data getters, particularly the specific-use getter functions, see: Data getters.
4.2.2. Event-Based Methods
The data getter functions can be specified as callbacks to be connected to specific events. For instance, we can connect functions to process left finger data only when data packets corresponding to the left eteeController are received. To learn more, see: 4.4. Event-Based Programming.
4.3. How IMU Data Is Processed
The serial data includes raw IMU data which consist of accelerometer, gyroscope and magnetometer data. Data getter methods are available for IMU data retrieval, as defined in: Data getters. If the corresponding IMU data exists (i.e. is different from None), the data getters will return a list containing their x, y and z-axis values.
1# Data getter for accelerometer
2left_accel = etee.get_accel("left")
3left_accel_x = left_accel[0]
4
5# Data getters for gyroscope
6left_gyro = etee.get_gyro("left")
7left_gyro_y = left_gyro[1]
8
9# Data getters for magnetometer
10left_mag = etee.get_mag("left")
11left_mag_z = left_mag[2]
The API library also provides methods to retrieve orientation data in the form of quaternions. The quaternion is computed during each data loop.
1# Data getters for quaternions
2quaternion_left = etee.get_quaternion("left")
3quaternion_right = etee.get_quaternion("right")
Before using quaternions, update_imu() should be called. This function retrieves the IMU calibration data stored in the eteeControllers and uses it to compute the quaternions. Without calling this function, the calculated quaternions will not use the latest IMU calibration data. The IMU can be re-calibrated using the eteeConnect software, which will modify the internal IMU calibration parameters.
For orientation data, the user can also choose to use absolute or relative orientation. The former uses magnetometer data, while the latter does not. By default, absolute orientation is enabled.
1# Absolute orientation is the default, but it can also be set as shown below
2# This will use the magnetometer data.
3etee.enable_absolute_imu(True)
4
5# To disable the absolute orientation and switch to relative orientation
6# This will NOT use the magnetometer data.
7etee.enable_absolute_imu(False)
4.4. Event-Based Programming
The etee API library supports event-based programming. Several serial and data events are defined. Each event can be connected to callback functions which will be triggered when the event is identified within the data loop.
A callback function can be connected to an event by calling the connect() method.
The data events left_hand_received and right_hand_received occur respectively when data packets from the left or the right eteeController are received. In the code sample below, as long as the data loop is running, the processing functions will be called every time the corresponding hand data packet is received.
1# Processing functions
2def process_left_hand():
3 left_fingers_pulls, left_fingers_forces = etee.get_device_finger_pressures("left")
4 print(f"The pressure of the left pinky finger is: pull = {left_fingers_pulls[4]}, force = {left_fingers_forces[4]}.")
5
6def process_right_hand():
7 right_fingers_pulls, right_fingers_forces = etee.get_device_finger_pressures("right")
8 print(f"The pressure of the right thumb finger is: pull = {right_fingers_pulls[4]}, force = {right_fingers_forces[4]}.")
9
10# Connect the processing functions as callbacks for the events
11etee.left_hand_received.connect(process_left_hand)
12etee.right_hand_received.connect(process_right_hand)
Another example of data events are left_hand_lost and right_hand_lost. These events are triggered when the signal is lost from the left and right eteeController, respectively. Signal loss is defined as no data having been received from the eteeControllers in the last 0.5 seconds.
1# Functions to be invoked
2def on_left_hand_lost():
3 print(f"The left data was lost.")
4
5def on_right_hand_lost():
6 print(f"The right data was lost.")
7
8# Connect the functions as callbacks for the events
9etee.left_hand_lost.connect(on_left_hand_lost)
10etee.right_hand_lost.connect(on_right_hand_lost)
An example of a serial event is dongle_disconnected, which occurs when the serial connection to the eteeDongle is disrupted.
1# Function to be invoked
2def on_dongle_disconnect():
3 print(f"The eteeDongle has been disconnected.")
4
5# Connect the function as a callback for the event
6etee.dongle_disconnected.connect(on_dongle_disconnect)
For the full API library reference for data and serial events, see: Data getters.
4.6. Resetting Sensor Baselines
If the finger curl data or other sensor data seem wrong, the easiest way to fix this is by triggering a quick calibration.
Quick calibration resets the electrodes signal baseline. For instance, if your real index finger is fully open but your virtual one appears to be flexed (i.e. index_pull is 55, instead of 0), a quick calibration will fix the issue (i.e. index_pull will be reset to 0).
Steps for quick calibration:
Please, ensure that your or the user’s fingers are fully stretched out, as illustrated below.
Trigger quick calibration by using API commands or the physical button.
API commands: You can send a quick calibration command to both or a single eteeController by writing the commands through serial communication to the eteeDongle.
1# Quick calibrate all devices connected to eteeDongle 2response = self.driver.send_command(b"BP+AB\r\n") 3 4# Quick calibrate the right eteeController if connected to eteeDongle 5response = self.driver.send_command(b"BR+AB\r\n") 6 7# The response returns 'OK' when the command is successfully sent 8print(response)Physical button: You can also trigger quick calibration by double-clicking the system button of the eteeController that you wish to reset the baselines.
This process is instantaneous and does not require any waiting time.
Note
This is not the same as the full/advanced calibration that takes place in eteeConnect.
We won’t be providing any commands for this as it’s a complicated step by step process. However, you should only need to run a full/advanced calibration if a different person is using the eteeControllers. In all other cases, a quick calibration will suffice.