-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
771a6b1
commit 0e37324
Showing
12 changed files
with
613 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
//Advanced settings, only for the pros XD | ||
|
||
#define LOOP_TIME 4 //How much time between data sends (ms), set to 0 for a good time :) | ||
#define CALIBRATION_LOOPS -1//How many loops should be calibrated. Set to -1 to always be calibrated. | ||
|
||
//Comm defines, no touchy | ||
#define COMM_SERIAL 0 | ||
#define COMM_BTSERIAL 1 | ||
|
||
//Encoding | ||
#define ENCODING 1 | ||
#define ENCODE_LEGACY 0 | ||
#define ENCODE_ALPHA 1 | ||
|
||
//Finger indeces (not used for legacy) | ||
#define PINKY_IND 4 | ||
#define RING_IND 3 | ||
#define MIDDLE_IND 2 | ||
#define INDEX_IND 1 | ||
#define THUMB_IND 0 | ||
|
||
//Automatically set ANALOG_MAX depending on the microcontroller | ||
#if defined(__AVR__) | ||
#define ANALOG_MAX 1023 | ||
#elif defined(ESP32) | ||
#define ANALOG_MAX 4095 | ||
#endif | ||
|
||
|
||
//ANALOG_MAX OVERRIDE: | ||
//uncomment and set as needed (only touch if you know what you are doing) | ||
//#define ANALOG_MAX 4095 | ||
|
||
#ifndef ANALOG_MAX | ||
#error "This board doesn't have an auto ANALOG_MAX assignment, please set it manually by uncommenting ANALOG_MAX OVERRIDE!" | ||
#endif | ||
|
||
//Filtering and clamping analog inputs | ||
#define CLAMP_ANALOG_MAP true //clamp the mapped analog values from 0 to ANALOG_MAX | ||
|
||
// Enable and set min and max to match your sensor's expected raw value range | ||
// This discards any spurious values outside of the useful range | ||
#define CLAMP_FLEXION false //clamp the raw flexion values | ||
#define CLAMP_MIN 0 //the minimum value from the flexion sensors | ||
#define CLAMP_MAX ANALOG_MAX //the maximum value from the flexion sensors | ||
|
||
// You must install RunningMedian library to use this feature | ||
// https://www.arduino.cc/reference/en/libraries/runningmedian/ | ||
#define ENABLE_MEDIAN_FILTER false //use the median of the previous values, helps reduce noise | ||
#define MEDIAN_SAMPLES 20 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/*struct inputData { | ||
int* flexion; | ||
int joyX; | ||
int joyY; | ||
bool joyClick; | ||
bool triggerButton; | ||
bool aButton; | ||
bool bButton; | ||
bool grab; | ||
bool pinch; | ||
}; | ||
struct outputData{ | ||
int* hapticLimits; | ||
}; | ||
*/ | ||
|
||
#if ENCODING == ENCODING_LEGACY | ||
//legacy encoding | ||
char* encode(int* flexion, int joyX, int joyY, bool joyClick, bool triggerButton, bool aButton, bool bButton, bool grab, bool pinch, bool calib, bool menu){ | ||
static char stringToEncode[75]; | ||
|
||
sprintf(stringToEncode, "%d&%d&%d&%d&%d&%d&%d&%d&%d&%d&%d&%d&%d\n", | ||
flexion[0], flexion[1], flexion[2], flexion[3], flexion[4], | ||
joyX, joyY, joyClick, | ||
triggerButton, aButton, bButton, grab, pinch | ||
); | ||
return stringToEncode; | ||
} | ||
//legacy decoding | ||
void decodeData(char* stringToDecode, int* hapticLimits){ | ||
byte index = 0; | ||
char* ptr = strtok(stringToDecode, "&"); // takes a list of delimiters | ||
while(ptr != NULL) | ||
{ | ||
hapticLimits[index] = atoi(ptr); | ||
index++; | ||
ptr = strtok(NULL, "&"); // takes a list of delimiters | ||
} | ||
} | ||
#endif | ||
|
||
#if ENCODING == ENCODE_ALPHA | ||
//alphabetic encoding | ||
char* encode(int* flexion, int joyX, int joyY, bool joyClick, bool triggerButton, bool aButton, bool bButton, bool grab, bool pinch, bool calib, bool menu){ | ||
static char stringToEncode[75]; | ||
int trigger = (flexion[1] > ANALOG_MAX/2) ? (flexion[1] - ANALOG_MAX/2) * 2:0; | ||
sprintf(stringToEncode, "A%dB%dC%dD%dE%dF%dG%dP%d%s%s%s%s%s%s%s%s\n", | ||
flexion[0], flexion[1], flexion[2], flexion[3], flexion[4], | ||
joyX, joyY, trigger, joyClick?"H":"", | ||
triggerButton?"I":"", aButton?"J":"", bButton?"K":"", grab?"L":"", pinch?"M":"", menu?"N":"", calib?"O":"" | ||
); | ||
return stringToEncode; | ||
} | ||
|
||
//legacy decoding | ||
void decodeData(char* stringToDecode, int* hapticLimits){ | ||
hapticLimits[0] = getArgument(stringToDecode, 'A'); //thumb | ||
hapticLimits[1] = getArgument(stringToDecode, 'B'); //index | ||
hapticLimits[2] = getArgument(stringToDecode, 'C'); //middle | ||
hapticLimits[3] = getArgument(stringToDecode, 'D'); //ring | ||
hapticLimits[4] = getArgument(stringToDecode, 'E'); //pinky | ||
//Serial.println("Haptic: "+ (String)hapticLimits[0] + " " + (String)hapticLimits[1] + " " + (String)hapticLimits[2] + " " + (String)hapticLimits[3] + " " + (String)hapticLimits[4] + " "); | ||
} | ||
|
||
int getArgument(char* stringToDecode, char command){ | ||
char* start = strchr(stringToDecode, command); | ||
if (start == NULL) | ||
return -1; | ||
else | ||
return atoi(start + 1); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//Interface for communication | ||
|
||
class ICommunication { | ||
|
||
public: | ||
virtual bool isOpen() = 0; | ||
|
||
virtual void start() = 0; | ||
|
||
virtual void output(char* data) = 0; | ||
|
||
virtual bool readData(char* input) = 0; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 LucidVR | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
# VRHapticGlove | ||
Critical Making's take on the Lucid gloves open source project | ||
# lucidgloves-firmware | ||
|
||
|
||
Check the [Wiki](https://github.com/LucidVR/lucidgloves/wiki/Firmware-Setup-and-Customization-Tutorial/) for instructions on how to set it up. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
//only compiles if BTSerial is set because it won't compile for a non-compatible board | ||
#if COMMUNICATION == COMM_BTSERIAL | ||
#include "BluetoothSerial.h" | ||
class BTSerialCommunication : public ICommunication { | ||
private: | ||
bool m_isOpen; | ||
BluetoothSerial m_SerialBT; | ||
|
||
public: | ||
BTSerialCommunication() { | ||
m_isOpen = false; | ||
} | ||
|
||
bool isOpen(){ | ||
return m_isOpen; | ||
} | ||
|
||
void start(){ | ||
Serial.begin(115200); | ||
m_SerialBT.begin(BTSERIAL_DEVICE_NAME); | ||
Serial.println("The device started, now you can pair it with bluetooth!"); | ||
m_isOpen = true; | ||
} | ||
|
||
void output(char* data){ | ||
m_SerialBT.print(data); | ||
} | ||
|
||
bool readData(char* input){ | ||
/*byte size = m_SerialBT.readBytesUntil('\n', input, 100); | ||
input[size] = NULL;*/ | ||
String message = m_SerialBT.readStringUntil('\n'); | ||
strcpy(input, message.c_str()); | ||
return input != NULL && strlen(input) > 0; | ||
} | ||
}; | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
class SerialCommunication : public ICommunication { | ||
private: | ||
bool m_isOpen; | ||
|
||
public: | ||
SerialCommunication() { | ||
m_isOpen = false; | ||
} | ||
|
||
bool isOpen(){ | ||
return m_isOpen; | ||
} | ||
|
||
void start(){ | ||
//Serial.setTimeout(1000000); | ||
Serial.begin(SERIAL_BAUD_RATE); | ||
m_isOpen = true; | ||
} | ||
|
||
void output(char* data){ | ||
Serial.print(data); | ||
Serial.flush(); | ||
} | ||
|
||
bool readData(char* input){ | ||
byte size = Serial.readBytesUntil('\n', input, 100); | ||
input[size] = NULL; | ||
return input != NULL && strlen(input) > 0; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#define ALWAYS_CALIBRATING CALIBRATION_LOOPS == -1 | ||
|
||
#define CALIB_OVERRIDE false | ||
#if USING_CALIB_PIN && COMMUNICATION == COMM_SERIAL && PIN_CALIB == 0 && !CALIB_OVERRIDE | ||
#error "You can't set your calibration pin to 0 over usb. You can calibrate with the BOOT button when using bluetooth only. Set CalibOverride to true to override this." | ||
#endif | ||
|
||
ICommunication* comm; | ||
int loops = 0; | ||
void setup() { | ||
#if COMMUNICATION == COMM_SERIAL | ||
comm = new SerialCommunication(); | ||
#elif COMMUNICATION == COMM_BTSERIAL | ||
comm = new BTSerialCommunication(); | ||
#endif | ||
comm->start(); | ||
|
||
setupInputs(); | ||
|
||
#if USING_FORCE_FEEDBACK | ||
setupServoHaptics(); | ||
#endif | ||
|
||
} | ||
|
||
void loop() { | ||
if (comm->isOpen()){ | ||
#if USING_CALIB_PIN | ||
bool calibButton = getButton(PIN_CALIB) != INVERT_CALIB; | ||
if (calibButton) | ||
loops = 0; | ||
#else | ||
bool calibButton = false; | ||
#endif | ||
|
||
bool calibrate = false; | ||
if (loops < CALIBRATION_LOOPS || ALWAYS_CALIBRATING){ | ||
calibrate = true; | ||
loops++; | ||
} | ||
|
||
int* fingerPos = getFingerPositions(calibrate, calibButton); | ||
bool joyButton = getButton(PIN_JOY_BTN) != INVERT_JOY; | ||
|
||
#if TRIGGER_GESTURE | ||
bool triggerButton = triggerGesture(fingerPos); | ||
#else | ||
bool triggerButton = getButton(PIN_TRIG_BTN) != INVERT_TRIGGER; | ||
#endif | ||
|
||
bool aButton = getButton(PIN_A_BTN) != INVERT_A; | ||
bool bButton = getButton(PIN_B_BTN) != INVERT_B; | ||
|
||
#if GRAB_GESTURE | ||
bool grabButton = grabGesture(fingerPos); | ||
#else | ||
bool grabButton = getButton(PIN_GRAB_BTN) != INVERT_GRAB; | ||
#endif | ||
|
||
#if PINCH_GESTURE | ||
bool pinchButton = pinchGesture(fingerPos); | ||
#else | ||
bool pinchButton = getButton(PIN_PNCH_BTN) != INVERT_PINCH; | ||
#endif | ||
|
||
bool menuButton = getButton(PIN_MENU_BTN) != INVERT_MENU; | ||
|
||
comm->output(encode(fingerPos, getJoyX(), getJoyY(), joyButton, triggerButton, aButton, bButton, grabButton, pinchButton, calibButton, menuButton)); | ||
|
||
#if USING_FORCE_FEEDBACK | ||
char received[100]; | ||
if (comm->readData(received)){ | ||
int hapticLimits[5]; | ||
//This check is a temporary hack to fix an issue with haptics on v0.5 of the driver, will make it more snobby code later | ||
if(String(received).length() >= 10) { | ||
decodeData(received, hapticLimits); | ||
writeServoHaptics(hapticLimits); | ||
} | ||
} | ||
#endif | ||
delay(LOOP_TIME); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
bool grabGesture(int *flexion){ | ||
return (flexion[PINKY_IND] + flexion[RING_IND] + flexion[MIDDLE_IND] + flexion[INDEX_IND]) / 4 <= ANALOG_MAX/2 ? 0:1; | ||
} | ||
|
||
bool pinchGesture(int *flexion){ | ||
return (flexion[INDEX_IND] + flexion[THUMB_IND]) / 2 <= ANALOG_MAX/2 ? 0:1; | ||
} | ||
|
||
bool triggerGesture(int *flexion){ | ||
return flexion[INDEX_IND]<=(ANALOG_MAX/2)?0:1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#if USING_FORCE_FEEDBACK | ||
|
||
#if defined(ESP32) | ||
#include "ESP32Servo.h" | ||
#else | ||
#include "Servo.h" | ||
#endif | ||
|
||
Servo pinkyServo; | ||
Servo ringServo; | ||
Servo middleServo; | ||
Servo indexServo; | ||
Servo thumbServo; | ||
|
||
void setupServoHaptics(){ | ||
pinkyServo.attach(PIN_PINKY_MOTOR); | ||
ringServo.attach(PIN_RING_MOTOR); | ||
middleServo.attach(PIN_MIDDLE_MOTOR); | ||
indexServo.attach(PIN_INDEX_MOTOR); | ||
thumbServo.attach(PIN_THUMB_MOTOR); | ||
} | ||
|
||
//static scaling, maps to entire range of servo | ||
void scaleLimits(int* hapticLimits, float* scaledLimits){ | ||
for (int i = 0; i < 5; i++){ | ||
scaledLimits[i] = 180.0f - hapticLimits[i] / 1000.0f * 180.0f; | ||
} | ||
} | ||
|
||
//dynamic scaling, maps to the limits calibrated from your finger | ||
void dynScaleLimits(int* hapticLimits, float* scaledLimits){ | ||
//will be refactored to take min and max as an argument | ||
|
||
/* this implementation of dynamic scaling relies on the assumption | ||
* that the servo reaches 2/3 of the potentiometer's range, | ||
* and that 0 degrees is geared to the start of the potentiometer. | ||
* Different hardware types may need to handle dynamic scaling differently. | ||
*/ | ||
for (int i = 0; i < sizeof(hapticLimits); i++){ | ||
scaledLimits[i] = hapticLimits[i] / 1000.0f * 180.0f; | ||
} | ||
} | ||
|
||
void writeServoHaptics(int* hapticLimits){ | ||
float scaledLimits[5]; | ||
scaleLimits(hapticLimits, scaledLimits); | ||
if(hapticLimits[0] >= 0) thumbServo.write(scaledLimits[0]); | ||
if(hapticLimits[1] >= 0) indexServo.write(scaledLimits[1]); | ||
if(hapticLimits[2] >= 0) middleServo.write(scaledLimits[2]); | ||
if(hapticLimits[3] >= 0) ringServo.write(scaledLimits[3]); | ||
if(hapticLimits[4] >= 0) pinkyServo.write(scaledLimits[4]); | ||
} | ||
|
||
#endif |
Oops, something went wrong.