Skip to content

Commit

Permalink
Add device implementation (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
RiccardoGrieco authored Mar 16, 2023
2 parents 6dd95b6 + 7969378 commit 5db752b
Showing 20 changed files with 1,693 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -30,3 +30,6 @@
*.exe
*.out
*.app

# Build directory
build/
34 changes: 34 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.5)

set(GLOBAL_PROJECT_VERSION "0.0.1")

project(FreeEmg VERSION ${GLOBAL_PROJECT_VERSION}
LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(GNUInstallDirs)

# Export all symbols in Windows
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

# Libraries type
if(MSVC)
option(BUILD_SHARED_LIBS "Build libraries as shared as opposed to static" OFF)
else()
option(BUILD_SHARED_LIBS "Build libraries as shared as opposed to static" ON)
endif()

# Control where binaries and libraries are placed in the build folder.
# This simplifies tests running in Windows.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

find_package(YARP 3.7.2 QUIET)
set(YARP_FORCE_DYNAMIC_PLUGINS ON)

add_subdirectory(devices)
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
# yarp-devices-bts-freeemg
YARP wearable device implementation for the BTS FREEEMG system

## Installation (Windows only)

Dependencies:
- [`YARP`](https://github.com/robotology/yarp)
- FREEEMG SDK: ask the vendor for the libraries

Starting from the directory where you cloned this repo, follow the steps below to install the device:

>:warning::warning: This operation required Administrator privileges. Open the terminal with right-click -> Run as administrator :warning::warning:
```bat
:: create the build directory
mkdir build
:: enter the directory
cd build
:: setup the build
:: replace <freeemg_sdk_root_directory> with your specific directory. Beware the spaces in the path! Enclose it in ""
cmake -G"Visual Studio 17 2022" .. -DFREEEMG_SDK_DIR=<freeemg_sdk_root_directory> -DCMAKE_INSTALL_PREFIX="./install"
:: build and install
cmake --build . --config Release --target INSTALL
```
>:warning: Change the Visual Studio version according to your installed version
>:warning: You can also set the FREEEMG_SDK_DIR environment variable instead of passing it to the cmake command
These will install the device and related files in the subdirectory `build/install`.

Finally, make the device available for YARP to use it by updating the following environment variables:

- `PATH`
Add `<installation-directory>\lib\yarp`
- `YARP_DATA_DIRS`
Add `<installation-directory>\share\yarp`
Add `<installation-directory>\share\FreeEmg`

### Running the device

The device can be open using `yarpdev --device freeemg` (`yarpserver` must be running). See also the `yarprobotinterface` [configuration files](devices/FreeEmgWearableDevice/conf/README.md) for the parameters that must/can be used.

### Applications

There are some default applications that can be run using the device. You can check them out [here](devices/FreeEmgWearableDevice/applications).

Maintainers
--------------
1 change: 1 addition & 0 deletions devices/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(FreeEmgWearableDevice)
61 changes: 61 additions & 0 deletions devices/FreeEmgWearableDevice/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
IF (NOT WIN32)
message(FATAL_ERROR "The device is available only on Windows")
ENDIF()

find_package(IWear REQUIRED)

if(NOT DEFINED FREEEMG_SDK_DIR)
if(DEFINED ENV{FREEEMG_SDK_DIR})
set(FREEEMG_SDK_DIR $ENV{FREEEMG_SDK_DIR})
else()
message(FATAL_ERROR "Cannot find FREEEMG_SDK_DIR!")
endif()
endif()

# Register DLLs
get_filename_component(DOT_NET_INSTALL_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full;InstallPath]" ABSOLUTE)
if(DOT_NET_INSTALL_PATH STREQUAL "/registry")
message(FATAL_ERROR "Unable to locate .NET Framework v4 installation!")
endif()
cmake_path(CONVERT ${DOT_NET_INSTALL_PATH} TO_NATIVE_PATH_LIST DOT_NET_INSTALL_NATIVE_PATH)
cmake_path(CONVERT ${CMAKE_CURRENT_SOURCE_DIR} TO_NATIVE_PATH_LIST CMAKE_CURRENT_SOURCE_DIR_NATIVE)

add_custom_target(
PreBuild
COMMAND cmd /k "${CMAKE_CURRENT_SOURCE_DIR_NATIVE}\\build_scripts\\PreBuild.bat" "$<CONFIG>" "${DOT_NET_INSTALL_NATIVE_PATH}" "${FREEEMG_SDK_DIR}" "${CMAKE_CURRENT_SOURCE_DIR_NATIVE}" "x64"
)

# Compile the plugin by default
yarp_prepare_plugin(freeemg TYPE wearable::devices::FreeEmgDevice
INCLUDE include/FreeEmgDevice.h
CATEGORY device
ADVANCED
DEFAULT ON
)

yarp_add_plugin(freeemg_device src/FreeEmgDevice.cpp src/BioDAQUtils.cpp
include/FreeEmgDevice.h)

target_link_libraries(freeemg_device
PUBLIC
IWear::IWear YARP::YARP_dev YARP::YARP_os
)

target_include_directories(freeemg_device
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE include_private)

# Run the DLLs registering script before build
add_dependencies(freeemg_device PreBuild)

# Install the device
yarp_install(TARGETS freeemg_device
COMPONENT runtime
LIBRARY DESTINATION ${YARP_DYNAMIC_PLUGINS_INSTALL_DIR}
ARCHIVE DESTINATION ${YARP_STATIC_PLUGINS_INSTALL_DIR}
YARP_INI DESTINATION ${YARP_PLUGIN_MANIFESTS_INSTALL_DIR})


# Install configuration files and applications
add_subdirectory(conf)
add_subdirectory(applications)
6 changes: 6 additions & 0 deletions devices/FreeEmgWearableDevice/applications/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

# FreeEmg xml application files installation
file (GLOB FREE_EMG_APP_XML_FILES *.xml)

install(FILES ${FREE_EMG_APP_XML_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/yarp/applications/)
22 changes: 22 additions & 0 deletions devices/FreeEmgWearableDevice/applications/FREEEMG_Log.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<application>

<!-- Generic information-->
<name>FREEEMG_Log</name>
<description>Log the EMG signals</description>
<version>0.0.1</version>

<authors>
<author email="riccardo.grieco@hotmail.com"> Riccardo Grieco </author>
</authors>

<module>
<name>yarprobotinterface</name>
<parameters>--config freeemg.xml --period 0.01 --COM-ports (26)</parameters>
</module>

<module>
<name>yarprobotinterface</name>
<parameters>--config freeEMG_logger.xml --loggerType "(matlab)" --period 0.01</parameters>
</module>

</application>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<application>

<!-- Generic information-->
<name>FREEEMG_Visualization</name>
<description>Plot the EMG signals</description>
<version>0.0.1</version>

<authors>
<author email="riccardo.grieco@hotmail.com"> Riccardo Grieco </author>
</authors>

<module>
<name>yarprobotinterface</name>
<parameters>--config freeemg.xml --period 0.01 --COM-ports (26)</parameters>
</module>

<module>
<name>yarprobotinterface</name>
<parameters>--config freeEMG_logger.xml --loggerType "(yarp)" --period 0.01</parameters>
</module>

<module>
<name>yarpscope</name>
<parameters>--xml freeEmg_scope.xml</parameters>
</module>
</application>
13 changes: 13 additions & 0 deletions devices/FreeEmgWearableDevice/applications/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# FreeEMG device - applications

In this directory we store the `yarpmanager` applications based on the FreeEmg weareable device.

The applications use the [provided configuration files](../conf/). Check the [configuration file directory README](../conf/README.md) for the list of parameters that can be overridden.

### FreeEmgLog

The application [`FreeEmgLog`](FreeEmgLog.xml) allows the user to save EMG signal data in a `.mat` file.

### FreeEmgVisualization

The application [`FreeEmgVisualization`](FreeEmgVisualization.xml) allows the user to see a plot of the EMG signals.
74 changes: 74 additions & 0 deletions devices/FreeEmgWearableDevice/build_scripts/PreBuild.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@echo off
rem ----------------------------------------------------------------------------

rem ---- Test Configuration Name
if %1 == Debug goto CONFIGNAME_OK
if %1 == Release goto CONFIGNAME_OK
if %1 == RelWithDebInfo goto CONFIGNAME_OK
echo Error during PreBuild step: Invalid Configuration - %1
goto END
:CONFIGNAME_OK

rem ---------------------------------------
rem ---- CONFIGURATIONS
rem ---------------------------------------

set DOT_NET_INSTALL_PATH=%~2
set FREEEMG_SDK_DIR=%~3
set Device_DIR=%~4
set PLATFORM=%~5

echo DOT_NET_INSTALL_PATH %DOT_NET_INSTALL_PATH%
echo FREEEMG_SDK_DIR %FREEEMG_SDK_DIR%
echo Device_DIR %Device_DIR%
echo PLATFORM %PLATFORM%

set TARGET_ROOT=%PROJECT_ROOT%..
set IMPORT_ROOT=%FREEEMG_SDK_DIR%\Bin

set IMPORT_NAME1=bts.biodaq.drivers
set IMPORT_NAME2=bts.biodaq.core

rem ---------------------------------------
rem ---- FOLDERS SETUP
rem ---------------------------------------

if %1 == Debug set CONFIG_FOLDER=Debug
if %1 == Release set CONFIG_FOLDER=Release
if %1 == RelWithDebInfo set CONFIG_FOLDER=Release

set SOURCE_FOLDER=%Device_DIR%\src
set IMPORT_FOLDER=%IMPORT_ROOT%\%CONFIG_FOLDER%\%PLATFORM%
set REGASM_FOLDER=%DOT_NET_INSTALL_PATH%

rem ---------------------------------------
rem ---- ALL CONFIGURATIONS
rem ---------------------------------------

echo Registering BioDaq libraries %IMPORT_NAME1%.dll and %IMPORT_NAME2%.dll
%DOT_NET_INSTALL_PATH%\RegAsm /codebase "%IMPORT_FOLDER%\%IMPORT_NAME1%.dll" /tlb: "%SOURCE_FOLDER%\%IMPORT_NAME1%.tlb"
%DOT_NET_INSTALL_PATH%\RegAsm /codebase "%IMPORT_FOLDER%\%IMPORT_NAME2%.dll" /tlb: "%SOURCE_FOLDER%\%IMPORT_NAME2%.tlb"

echo Copying type library mscorlib.tlb
call :FCOPY "%IMPORT_FOLDER%\mscorlib.tlb" "%SOURCE_FOLDER%"

goto END

rem ---------------------------------------
rem ---- SUBROUTINES
rem ----

:FCOPY

echo Copying %1 to %2
copy %1 %2 > Nul
if ERRORLEVEL 1 echo Error copying %1 to %2
goto :EOF


:END
rem ---------------------------------------
rem END
rem ---------------------------------------

echo PreBuild done.
6 changes: 6 additions & 0 deletions devices/FreeEmgWearableDevice/conf/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

# Install FreeEmg device configuration files
file (GLOB FREE_EMG_CONF_XML_FILES *.xml)

install(FILES ${FREE_EMG_CONF_XML_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/)
59 changes: 59 additions & 0 deletions devices/FreeEmgWearableDevice/conf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# FreeEMG device - configuration files

Here we store YARP configuration files to use the FreeEMG wearable device.

### Publish data

The `yarprobotinterface` configuration file [freeEmg](freeEmg.xml) opens the wearable device and publishes the data on a YARP port as a [WearableData](https://github.com/robotology/wearables/blob/a3a20863161e755f55277f204ca206764c3ed5f0/msgs/thrift/WearableData.thrift) messages.

List of overridable parameters when launching `yarprobotinterface`:

| Param name | Description |Required | Example/default |
|-------|---|----|------|
| period | Device frequency in seconds | :x: | 0.01|
| COM-ports | List of BMs COM ports| :heavy_check_mark: | (26) |
| labelList | List of probe labels to expose. Must have the same size as `sensorNames` | :heavy_check_mark: | (1 2) |
| sensorNames | List of the names associated to the probes. Must have the same size as `labelList` | :heavy_check_mark: | (r_tib_lat r_gastro_med) |
| useCustomProfile | Flag to set a custom sensor dictionary. If set to true, the parameter profile must be added (see file for an example) | :heavy_check_mark: | false |
| dataPortName | Name of the YARP port where data is published | :x: | /FreeEmg/WearableData/data:o |

To run the configuration:

```bat
yarprobotinterface --config freeemg.xml
```

### Log or stream analog data

The `yarprobotinterface` configuration file [`freeEMG_logger`](freeEMG_logger.xml) allows for two purposes:

1. Log the data as a `.mat` file
2. Stream the data as analog values

>:warning: This configuration file requires the data to being already streamed on a YARP port (e.g. using [the provided configuration file](#publish-data)).
List of overridable parameters when launching `yarprobotinterface`:

| Param name | Description |Required | Example/default |
|-------|---|----|------|
| period | Log/stream frequency | :x: | 0.01 |
| wearableDataPorts | YARP port(s) where data is being streamed | :x: | /FreeEmg/WearableData/data:o |
| loggerType | `matlab` if you want to log the data, `yarp` if you want to stream it | :x: | (matlab) |
| experimentName| Prefix of the file(s) created by the logger | :x: | wearable_data |

>:warning: The logger will create the file(s) in the working directory where the process using the file is running.
In streaming mode, the process will create one YARP port per sensor (probe) with the format `/FreeEmg/emg/<sensor_name>`, where the sensor names are the one configured in the wearable device via the `sensorNames` parameter.

To run the logger:

```bat
yarprobotinterface --config freeEMG_logger.xml
```

### Visualize EMG signals

The file [`freeEMG_scope`](freeEMG_scope.xml) is a `yarpscope` configuration file for visualizing the EMG signals streamed by the device.

In order to run the device, the values must be streamed in analog ports like the ones provided by the [related configuration file](#log-or-stream-analog-data).

Loading

0 comments on commit 5db752b

Please sign in to comment.