|
@@ -6,102 +6,190 @@ extern "C" {
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include "ArmbandInterface.h"
|
|
#include "ArmbandInterface.h"
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
|
|
+
|
|
|
|
+This is a static class acting as a interface for the BodActuator dll, which is plain C code and can't be called directly from C# (managed) code.
|
|
|
|
+Therefore this class will encapsulate all memory management necessary to instantiate and use an Object of the BodyActuator type, aswell as provide all modyfying methods to external callers.
|
|
|
|
+Basically, this class acts as a single static BodyActuator instance towards outside callers, and can be used from within managed (specifically C#) code.
|
|
|
|
+(side note: the use of the terms 'function' and 'method' might be a bit messy here...)
|
|
|
|
+*/
|
|
|
|
|
|
|
|
+
|
|
|
|
+function handles are defined as a custom type to be able to dynamically bind and use methods from the C dll (no lib, neither source code for BodyActuator available, therefore only dynamic linking is possible)
|
|
|
|
+*/
|
|
|
|
+
|
|
typedef void(__cdecl *InitFunctionType)(BodyActuator*, BodyActuator_Type, char*, int);
|
|
typedef void(__cdecl *InitFunctionType)(BodyActuator*, BodyActuator_Type, char*, int);
|
|
-typedef void(__cdecl *StopFunctionType)(BodyActuator*, uint8_t);
|
|
+
|
|
-typedef void(__cdecl *StartFunctionType)(BodyActuator*, uint8_t, float);
|
|
+typedef void(__cdecl *ClearFunctionType)(BodyActuator*);
|
|
-typedef void(__cdecl *ActuateFunctionType)(BodyActuator*, uint8_t, float, uint64_t);
|
|
+
|
|
typedef void(__cdecl *DeleteFunctionType)(BodyActuator*);
|
|
typedef void(__cdecl *DeleteFunctionType)(BodyActuator*);
|
|
|
|
+
|
|
|
|
+typedef void(__cdecl *ActuateFunctionType)(BodyActuator*, uint8_t, double, uint64_t);
|
|
|
|
+
|
|
|
|
+typedef void(__cdecl *StartFunctionType)(BodyActuator*, uint8_t, double);
|
|
|
|
+
|
|
|
|
+typedef void(__cdecl *StopFunctionType)(BodyActuator*, uint8_t);
|
|
|
|
+
|
|
|
|
+typedef void(__cdecl *SetFrequencyFunctionType)(BodyActuator*, uint8_t, uint16_t);
|
|
|
|
+
|
|
|
|
+typedef void(__cdecl *SetIntensityRangeFunctionType)(BodyActuator*, uint8_t, double, double);
|
|
|
|
|
|
|
|
+
|
|
|
|
+static variables to hold the dynamically linked function handles, one per linked function in the BodyActuator dll
|
|
|
|
+*/
|
|
|
|
+
|
|
static InitFunctionType initFunctionHandle;
|
|
static InitFunctionType initFunctionHandle;
|
|
|
|
+
|
|
|
|
+static ClearFunctionType clearFunctionHandle;
|
|
|
|
+
|
|
|
|
+static DeleteFunctionType deleteFunctionHandle;
|
|
|
|
+
|
|
|
|
+static ActuateFunctionType actuateFunctionHandle;
|
|
|
|
+
|
|
static StartFunctionType startFunctionHandle;
|
|
static StartFunctionType startFunctionHandle;
|
|
|
|
+
|
|
static StopFunctionType stopFunctionHandle;
|
|
static StopFunctionType stopFunctionHandle;
|
|
-static ActuateFunctionType actuateFunctionHandle;
|
|
+
|
|
-static DeleteFunctionType deleteFunctionHandle;
|
|
+static SetFrequencyFunctionType setFrequencyFunctionHandle;
|
|
|
|
+
|
|
|
|
+static SetIntensityRangeFunctionType setIntensityRangeFunctionHandle;
|
|
|
|
|
|
-static BodyActuator* armband;
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
+
|
|
static HINSTANCE lib;
|
|
static HINSTANCE lib;
|
|
|
|
|
|
|
|
+
|
|
|
|
+static BodyActuator* armband;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
extern "C" {
|
|
extern "C" {
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public initialization method for external calls, loading the BodyActuator dll and linking its methods to the previously defined function
|
|
|
|
+ handles, aswell as creating and initializing the single static BodyActuator object afterwards (allocates memory to that pointer without
|
|
|
|
+ releasing it, as the pointer is still needed outside of this method -> mus be freed later)
|
|
|
|
+ return value may be used for debugging purposes and holds no other purpose
|
|
|
|
+ */
|
|
DllExport int __cdecl ArmbandInterface::setupArmband() {
|
|
DllExport int __cdecl ArmbandInterface::setupArmband() {
|
|
- lib = LoadLibrary(TEXT("BodyActuator.dll"));
|
|
+
|
|
- if (lib == NULL) {
|
|
+ lib = LoadLibrary(TEXT("BodyActuator.dll"));
|
|
- printf("ERROR: library could not be loaded");
|
|
+ if (lib == NULL) {
|
|
- return 0;
|
|
+ printf("ERROR: library could not be loaded");
|
|
- }
|
|
+ return 0;
|
|
- initFunctionHandle = (InitFunctionType)GetProcAddress(lib, "BodyActuator_init");
|
|
+ }
|
|
- if (initFunctionHandle == NULL) {
|
|
+
|
|
- printf("ERROR: init function could not be retrieved");
|
|
+ initFunctionHandle = (InitFunctionType)GetProcAddress(lib, "BodyActuator_init");
|
|
- return 1;
|
|
+ if (initFunctionHandle == NULL) {
|
|
- }
|
|
+ printf("ERROR: init function could not be retrieved");
|
|
- startFunctionHandle = (StartFunctionType)GetProcAddress(lib, "BodyActuator_startActuation");
|
|
+ return 1;
|
|
- if (startFunctionHandle == NULL) {
|
|
+ }
|
|
- printf("ERROR: start function could not be retrieved");
|
|
+ clearFunctionHandle = (ClearFunctionType)GetProcAddress(lib, "BodyActuator_clear");
|
|
- return 2;
|
|
+ if (clearFunctionHandle == NULL) {
|
|
- }
|
|
+ printf("ERROR: init function could not be retrieved");
|
|
- stopFunctionHandle = (StopFunctionType)GetProcAddress(lib, "BodyActuator_stopActuation");
|
|
+ return 2;
|
|
|
|
+ }
|
|
|
|
+ deleteFunctionHandle = (DeleteFunctionType)GetProcAddress(lib, "BodyActuator_delete");
|
|
|
|
+ if (deleteFunctionHandle == NULL) {
|
|
|
|
+ printf("ERROR: delete function could not be retrieved");
|
|
|
|
+ return 3;
|
|
|
|
+ }
|
|
|
|
+ startFunctionHandle = (StartFunctionType)GetProcAddress(lib, "BodyActuator_startActuation");
|
|
|
|
+ if (startFunctionHandle == NULL) {
|
|
|
|
+ printf("ERROR: start function could not be retrieved");
|
|
|
|
+ return 4;
|
|
|
|
+ }
|
|
|
|
+ stopFunctionHandle = (StopFunctionType)GetProcAddress(lib, "BodyActuator_stopActuation");
|
|
if (stopFunctionHandle == NULL) {
|
|
if (stopFunctionHandle == NULL) {
|
|
- printf("ERROR: stop function could not be retrieved");
|
|
+ printf("ERROR: stop function could not be retrieved");
|
|
- return 3;
|
|
+ return 5;
|
|
- }
|
|
|
|
- actuateFunctionHandle = (ActuateFunctionType)GetProcAddress(lib, "BodyActuator_actuate");
|
|
|
|
- if (actuateFunctionHandle == NULL) {
|
|
|
|
- printf("ERROR: actuate function could not be retrieved");
|
|
|
|
- return 4;
|
|
|
|
- }
|
|
|
|
- deleteFunctionHandle = (DeleteFunctionType)GetProcAddress(lib, "BodyActuator_delete");
|
|
|
|
- if (deleteFunctionHandle == NULL) {
|
|
|
|
- printf("ERROR: delete function could not be retrieved");
|
|
|
|
- return 5;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- setupMotors();
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- return -1;
|
|
|
|
}
|
|
}
|
|
-
|
|
+ actuateFunctionHandle = (ActuateFunctionType)GetProcAddress(lib, "BodyActuator_actuate");
|
|
- DllExport void __cdecl ArmbandInterface::startVibrate(int tactor, float intensity) {
|
|
+ if (actuateFunctionHandle == NULL) {
|
|
- (startFunctionHandle)(armband, 0, 1.0);
|
|
+ printf("ERROR: actuate function could not be retrieved");
|
|
- printf("sollte gehen");
|
|
+ return 6;
|
|
}
|
|
}
|
|
-
|
|
+ setFrequencyFunctionHandle = (SetFrequencyFunctionType)GetProcAddress(lib, "BodyActuator_setFrequency");
|
|
- DllExport void __cdecl ArmbandInterface::stopVibrate(int tactor) {
|
|
+ if (setFrequencyFunctionHandle == NULL) {
|
|
- (stopFunctionHandle)(armband, (uint8_t)tactor);
|
|
+ printf("ERROR: setFrequency function could not be retrieved");
|
|
|
|
+ return 7;
|
|
}
|
|
}
|
|
-
|
|
+ setIntensityRangeFunctionHandle = (SetIntensityRangeFunctionType)GetProcAddress(lib, "BodyActuator_setIntensityRange");
|
|
- DllExport void __cdecl ArmbandInterface::actuate100() {
|
|
+ if (setIntensityRangeFunctionHandle == NULL) {
|
|
- (actuateFunctionHandle)(armband, 0, 1.0, 20);
|
|
+ printf("ERROR: setIntensityRange function could not be retrieved");
|
|
|
|
+ return 8;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ setupMotors();
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
|
|
- DllExport void __cdecl ArmbandInterface::actuate66() {
|
|
+
|
|
- (actuateFunctionHandle)(armband, 0, 0.66, 20);
|
|
+ resets the instance of BodyActuator to a clean state
|
|
- }
|
|
+ */
|
|
|
|
+ DllExport void __cdecl ArmbandInterface::clearArmband() {
|
|
|
|
+ (clearFunctionHandle)(armband);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
- DllExport void __cdecl ArmbandInterface::actuate33() {
|
|
+
|
|
- (actuateFunctionHandle)(armband, 0, 0.33, 20);
|
|
+ destructor method destroying the instance of BodyActuator and freeing the memory held by the instance pointer
|
|
- }
|
|
+ */
|
|
|
|
+ DllExport void __cdecl ArmbandInterface::deleteArmband() {
|
|
|
|
+ (deleteFunctionHandle)(armband);
|
|
|
|
+ free(armband);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ start vibrating the specified tactor (number from 0 to 7) at the specified intensity until it is stopped (explicitly or implicitly)
|
|
|
|
+ provides access to the DLLs BodyActuator_startActuation method and handles type conversion to C types required by the DLL which are not available in C#
|
|
|
|
+ */
|
|
|
|
+ DllExport void __cdecl ArmbandInterface::startVibrate(int tactor, double intensity) {
|
|
|
|
+ (startFunctionHandle)(armband, tactor, intensity);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ explicitly stop actuating the specified tactor (number from 0 to 7)
|
|
|
|
+ provides access to the DLLs BodyActuator_stopActuation method and handles type conversion to C types required by the DLL which are not available in C#
|
|
|
|
+ */
|
|
|
|
+ DllExport void __cdecl ArmbandInterface::stopVibrate(int tactor) {
|
|
|
|
+ (stopFunctionHandle)(armband, (uint8_t)tactor);
|
|
|
|
+ }
|
|
|
|
|
|
- DllExport void __cdecl ArmbandInterface::deleteArmband() {
|
|
+
|
|
- (deleteFunctionHandle)(armband);
|
|
+ make the specified tactor (number from 0 to 7) actuate at a specified intensity (default: between 0.0 and 1.0, but range may be set using the setIntensityRange function) for the specified duration (number of milliseconds) ,or until it is stopped
|
|
- printf("armband deleted");
|
|
+ provides access to the DLLs BodyActuator_actuate method and handles type conversion to C types required by the DLL which are not available in C#
|
|
- }
|
|
+ */
|
|
|
|
+ DllExport void __cdecl ArmbandInterface::actuate(int tactor, double intensity, int duration) {
|
|
|
|
+ (actuateFunctionHandle)(armband, tactor, intensity, duration);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ sets the frequency of the specified tactor to a new value (unit unknown atm...)
|
|
|
|
+ */
|
|
|
|
+ DllExport void __cdecl ArmbandInterface::setFrequency(int tactor, int frequency) {
|
|
|
|
+ (setFrequencyFunctionHandle)(armband, tactor, frequency);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ sets a new intensity range for a single actuator to make different actuators react differently even when receiving an actuation command with the same intensity (e.g. to to compensate differing tactile sensitivity on different parts of the human body)
|
|
|
|
+ */
|
|
|
|
+ DllExport void __cdecl ArmbandInterface::setIntensityRange(int tactor, double minIntensity, double maxIntensity) {
|
|
|
|
+ (setIntensityRangeFunctionHandle)(armband, tactor, minIntensity, maxIntensity);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- void ArmbandInterface::setupMotors() {
|
|
+
|
|
|
|
+internal method to initialize the BodyActuator object (and handle the memory allocation involved)
|
|
|
|
+*/
|
|
|
|
+void ArmbandInterface::setupMotors() {
|
|
char* port = (char*) "COM5";
|
|
char* port = (char*) "COM5";
|
|
armband = (BodyActuator*) malloc(sizeof(BodyActuator*));
|
|
armband = (BodyActuator*) malloc(sizeof(BodyActuator*));
|
|
|
|
|
|
- (initFunctionHandle) (armband, BODYACTUATOR_TYPE_EAI, port, 8);
|
|
+ (initFunctionHandle) (armband, BODYACTUATOR_TYPE_EAI, port, 8);
|
|
- printf("armband initialized");
|
|
+
|
|
- }
|
|
+}
|
|
-
|
|
|
|
-
|
|
|
|
- (deleteFunctionHandle)(armband);
|
|
|
|
- }*/
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- (actuateFunctionHandle)(armband, tactor, intensity, duration);
|
|
|
|
-}*/
|
|
|