commit 98d237acb3dc1fdc015715eaaf52a46563d0a86c
Author: d3fault <d3fault@d3fault.net>
Date:   Sat May 20 15:56:24 2017 -0700

    wasdf: completed a huge refactor of business logic to support analog pin number detection of first (right index) finger. compiles and should work once I write a little more glue code

diff --git a/.lastModifiedTimestamps b/.lastModifiedTimestamps
index ca4aca7..addfff2 100644
--- a/.lastModifiedTimestamps
+++ b/.lastModifiedTimestamps
@@ -5878,26 +5878,25 @@ Projects/libAvGraphicsItem3/src/frontend/videoplayerwidget.cpp:1327006070
Projects/libAvGraphicsItem3/src/frontend/videoplayerwidget.h:1327005797
Projects/libAvGraphicsItem3/src/libAvGraphicsItem3.pro:1327004311
Projects/libAvGraphicsItem3/src/main.cpp:1327003410
Projects/wasdf/:1495254273Projects/wasdf/:1495320113
Projects/wasdf/assets/:1495250258
Projects/wasdf/assets/ArduinoWriteChangesOnAnalogPinstoSerial/:1495250286
Projects/wasdf/assets/ArduinoWriteChangesOnAnalogPinstoSerial/ArduinoWriteChangesOnAnalogPinstoSerial.cpp:1495243391
Projects/wasdf/design/:1495255816
Projects/wasdf/design/pin.detection.and.finger.mapping.are.same.step.as.calibration.txt:1495256263Projects/wasdf/design/pin.detection.and.finger.mapping.are.same.step.as.calibration.txt:1495315077
Projects/wasdf/design/renaming.from.MusicFingers.txt:1495250184
Projects/wasdf/src/:1495256691
Projects/wasdf/src/cli/:1495250620
Projects/wasdf/src/cli/main.cpp:1495250620
Projects/wasdf/src/lib/:1495254711
Projects/wasdf/src/lib/wasdf.cpp:1495254058
Projects/wasdf/src/lib/wasdf.h:1495253721
Projects/wasdf/src/lib/wasdfarduino.cpp:1495251264
Projects/wasdf/src/lib/wasdfarduino.h:1495253710
Projects/wasdf/src/lib/wasdfcalibrationconfiguration.h:1495253874
Projects/wasdf/src/lib/wasdfcalibrator.cpp:1495254711
Projects/wasdf/src/lib/wasdfcalibrator.h:1495254530
Projects/wasdf/src/wasdf-cli.pro:1495251027
Projects/wasdf/src/wasdf.pri:1495253341Projects/wasdf/src/:1495320856
Projects/wasdf/src/cli/:1495318115
Projects/wasdf/src/cli/main.cpp:1495318115
Projects/wasdf/src/lib/:1495320800
Projects/wasdf/src/lib/wasdf.cpp:1495320799
Projects/wasdf/src/lib/wasdf.h:1495320794
Projects/wasdf/src/lib/wasdfarduino.cpp:1495318591
Projects/wasdf/src/lib/wasdfarduino.h:1495318578
Projects/wasdf/src/lib/wasdfcalibrator.cpp:1495320763
Projects/wasdf/src/lib/wasdfcalibrator.h:1495320214
Projects/wasdf/src/wasdf-cli.pro:1495319518
Projects/wasdf/src/wasdf.pri:1495320067
Solutions/:1417412538
Solutions/Abc2PessimisticStateMonitorAndRecoverer/:1427380549
Solutions/Abc2PessimisticStateMonitorAndRecoverer/design/:1413188299
diff --git a/Projects/wasdf/design/pin.detection.and.finger.mapping.are.same.step.as.calibration.txt b/Projects/wasdf/design/pin.detection.and.finger.mapping.are.same.step.as.calibration.txt
index 86e083e..8ec27e8 100644
--- a/Projects/wasdf/design/pin.detection.and.finger.mapping.are.same.step.as.calibration.txt
+++ b/Projects/wasdf/design/pin.detection.and.finger.mapping.are.same.step.as.calibration.txt
@@ -21,4 +21,20 @@ Hmm ok forelobe'd it: after saying "move your pinky as far as you can", we can s

Maybe instead of a constant ~5 sec, a min/max timeout should be used: wait a min of 2 sec and a max of 15 sec. Once ~50% range of _only_ 1 of the 10 fingers has been "used"/utilized/calibrated _AND_ 2 sec (min) has elapsed, we move on. But if 15 seconds has elapsed, we'll settle with whatever finger moved the most (maybe a min of 10% utilization though?). If more than 1 finger utilizes >= ~50% range before that 2 seconds minimum, we tell the user to keep the other 9 fingers still and then start the process over (wait another 2 sec) -- loops infinitely until they behave (shit there are people with diseases who literally can't keep their hands still xDDDDD (but there are also people with greater than and less than 10 fingers (and same with the 2 hands assumption!))).

s/LeftPinky/RightIndex -- it just makes more sense for right index to be the "next"/confirm/A(in video game console terms)/yes/OK/etc finger rather than the awkward left pinky.


After sleeping on it I realized two things:
1) Don't need to have the step 1 above "move all 10 of your fingers". Since we are going to calibrate each finger anyways, pin detection can be done at the same time.
2) The concept of "50%" does not exist until AFTER calibrated. At least not accurately. 0-1023 is the range of the analog sensors, but in reality much less of that range will actually be used (and it [probably] won't start at 0 nor end at 1023, it will be some segment in between) -- that's the whole point of calibration, to determine the range actually used (both by the sensors AND the specific fingers (my pinky has less range than my index finger, for example))! Still there are two solutions (and ideally combining the two somehow would be best): a) the sensor that uses up the most range of 0-1023 is the finger we told them to move. b) the sensor that moves THE MOST (back and forth and back and forth. we keep track of "total distance moved") is the finger we told them to move. I actually like (b) better than (a) and can't off the top of my head think of a way to combine the two, so fuck it (b) it is! (weird I just came up with both (a) and (b) while writing out (2) :-D)


#########Ok so to restate the revised design clearly succinctly:
0) Move your right index finger
	After a couple seconds we select the analog pin that moved the most (total distance wise, not just the one that utilized the most of the 0-1023 range)
1) Either repeat (0) for the other 9 fingers, or use the right index finger from now on as an OK/Next(finger) trigger -- either one works. Fuck deciding now, I'll code (0) first and let it sit in ye ole' subconscience


TODOprobably: for step (0) just above there should maybe be a MINIMUM THRESHOLD of an amount of the 0-1023 range being utilized. people with that shaky hand disease might have an ultra fast vibrating finger that gives us a false positive for the "total distance moved". they might go from 0-5 (out of 0-1023) over and over REALLY fast unintentionally... and it might just marginally beat out their _intended_ finger that has a much larger range utilization. this shouldn't be in the first version, since it complicates things too much and is a corner case as well

TODOmb: like fps video games give you a chance (and preferably in-game, too!) to "invert" your aiming joystick, I too should give users a chance to change from their RIGHT index finger to their LEFT. My UIs should never say "curl your right index finger to continue", they should say "press [your?] OK [finger?] to continue"
diff --git a/Projects/wasdf/src/cli/main.cpp b/Projects/wasdf/src/cli/main.cpp
index b846117..19fa8c1 100644
--- a/Projects/wasdf/src/cli/main.cpp
+++ b/Projects/wasdf/src/cli/main.cpp
@@ -4,8 +4,8 @@ int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WasdfCli//WasdfCli cli;
    Q_UNUSED(cli)//Q_UNUSED(cli)

    return a.exec();
}
diff --git a/Projects/wasdf/src/lib/wasdf.cpp b/Projects/wasdf/src/lib/wasdf.cpp
index d5c67be..ee40e00 100644
--- a/Projects/wasdf/src/lib/wasdf.cpp
+++ b/Projects/wasdf/src/lib/wasdf.cpp
@@ -3,13 +3,14 @@
#include <QCoreApplication>
#include <QSettings>

#include "wasdfarduino.h"
#include "wasdfcalibrator.h"

#define SETTINGS_KEY_IS_CALIBRATED "isCalibrated"

Wasdf::Wasdf(QObject *parent)
    : QObject(parent)
    , m_Calibrator(0)m_Arduino(new WasdfArduino(this))
{
    QCoreApplication::setOrganizationName("wasdf organization");
    QCoreApplication::setOrganizationDomain("wasdf.com");
@@ -17,28 +18,35 @@ Wasdf::Wasdf(QObject *parent)
}
void Wasdf::startWasdfActualSinceCalibrated()
{
#ifdef TEMP_DSFLJDS
    m_Arduino.setMode(Normal, m_CalibrationConfig); //TODOreq: this is where the 10 fingers get mapped to the 10 pins
#endif
}
void Wasdf::startWasdf()
{
    m_Arduino.startCommunicatingOverSerialPort();//m_Arduino.startCommunicatingOverSerialPort();
    QSettings settings;
    bool isCalibrated = settings.value(SETTINGS_KEY_IS_CALIBRATED, false).toBool();
    if(!isCalibrated)
    {
#ifdef TEMP_DSFLJDS
        m_Arduino.setMode(Calibrating); //TODOreq: arduino sends _ALL_ (not just 10) analog pin readings over serial
#endif
        m_Calibrator = new WasdfCalibrator(this);
        connect(m_Calibrator.data(), SIGNAL(calibrationComplete(WasdfCalibrationConfiguration)),&WasdfCalibrator::calibrationComplete, this, SLOT(handleCalibrationComplete(WasdfCalibrationConfiguration)));&Wasdf::handleCalibrationComplete);
        QMetaObject::invokeMethod(m_Calibrator.data(), "startCalibrating");
    }
    else
    {
        //TODOreq: read WasdfCalibrationConfiguration out of the settings (or maybe just read values on-demand when needed)
        //m_WasdfCalibrationConfiguration = ;
        qDebug("Calibrated!");
        startWasdfActualSinceCalibrated();
    }
}
void Wasdf::handleCalibrationComplete(const WasdfCalibrationConfiguration &calibrationConfiguration)
{
    //m_WasdfCalibrationConfiguration = calibrationConfiguration;
    //TODoreq: write calibrationConfiguration to settings
    if(!m_Calibrator.isNull())
        m_Calibrator->deleteLater();
diff --git a/Projects/wasdf/src/lib/wasdf.h b/Projects/wasdf/src/lib/wasdf.h
index d903118..f6d047a 100644
--- a/Projects/wasdf/src/lib/wasdf.h
+++ b/Projects/wasdf/src/lib/wasdf.h
@@ -3,51 +3,69 @@

#include <QObject>

#include <QHash>
#include <QPointer>

class Wasdf : public QObjectWasdfArduino;
class WasdfCalibrator;

enum class Finger
{
Q_OBJECT
public:
    enum class Finger
    {    LeftPinky_Finger0 = 0
  , Finger0_LeftPinky = LeftPinky_Finger0

  , LeftRing_Finger1 = 1
  , Finger1_LeftRing = LeftRing_Finger1

  , LeftMiddle_Finger2 = 2
  , Finger2_LeftMiddle = LeftMiddle_Finger2

  , LeftIndex_Finger3 = 3
  , Finger3_LeftIndex = LeftIndex_Finger3

  , LeftThumb_Finger4 = 4
  , Finger4_LeftThumb = LeftThumb_Finger4

  , RightThumb_Finger5 = 5
  , Finger5_RightThumb = RightThumb_Finger5

  , RightIndex_Finger6 = 6
  , Finger6_RightIndex = RightIndex_Finger6

  , RightMiddle_Finger7 = 7
  , Finger7_RightMiddle = RightMiddle_Finger7

  , RightRing_Finger8 = 8
  , Finger8_RightRing = RightRing_Finger8

  , RightPinky_Finger9 = 9
  , Finger9_RightPinky = RightPinky_Finger9
};
inline uint qHash(const Finger &key, uint seed)
{
    return qHash(static_cast<uint>(key), seed);
}
struct WasdfCalibrationFingerConfiguration
{
    int AnalogPinIdOnArduino = -1;
    int MinValue = 1023;
    int MaxValue = 0;
};

, RightPinky_Finger9 = 9
      , Finger9_RightPinky = RightPinky_Finger9
    };typedef QHash<Finger, WasdfCalibrationFingerConfiguration> WasdfCalibrationConfiguration;

class Wasdf : public QObject
{
    Q_OBJECT
public:
    explicit Wasdf(QObject *parent = 0);
private:

    void startWasdfActualSinceCalibrated();

    Arduino m_Arduino;WasdfArduino *m_Arduino;
    QPointer<WasdfCalibrator> m_Calibrator;
    //WasdfCalibrationConfiguration m_WasdfCalibrationConfiguration;
public slots:
    void startWasdf();
private slots:
diff --git a/Projects/wasdf/src/lib/wasdfarduino.cpp b/Projects/wasdf/src/lib/wasdfarduino.cpp
index 712d430..0ff0dcb 100644
--- a/Projects/wasdf/src/lib/wasdfarduino.cpp
+++ b/Projects/wasdf/src/lib/wasdfarduino.cpp
@@ -1,5 +1,7 @@
#include "wasdfarduino.h"

#include "wasdf.h"

WasdfArduino::WasdfArduino(QObject *parent)
    : QSerialPort(parent)
{ }
diff --git a/Projects/wasdf/src/lib/wasdfarduino.h b/Projects/wasdf/src/lib/wasdfarduino.h
index 17926a3..aec12d3 100644
--- a/Projects/wasdf/src/lib/wasdfarduino.h
+++ b/Projects/wasdf/src/lib/wasdfarduino.h
@@ -3,6 +3,8 @@

#include <QtSerialPort/QSerialPort>

enum class Finger;

class WasdfArduino : private QSerialPort
{
    Q_OBJECT
diff --git a/Projects/wasdf/src/lib/wasdfcalibrationconfiguration.h b/Projects/wasdf/src/lib/wasdfcalibrationconfiguration.h
deleted file mode 100644
index d6bd4f4..0000000
--- a/Projects/wasdf/src/lib/wasdfcalibrationconfiguration.h
+++ /dev/null
@@ -1,26 +0,0 @@
#ifndef WASDFCALIBRATIONCONFIGURATION_H
#define WASDFCALIBRATIONCONFIGURATION_H

#include <QHash>

#include "wasdf.h"

struct WasdfCalibrationConfigurationFinger
{
    int MinValue = 1023;
    int MaxValue = 0;
};

struct WasdfCalibrationConfiguration
{
    WasdfCalibrationConfiguration()
    {
        for(Finger finger = Finger0_LeftPinky; finger <= Finger9_RightPinky; ++finger)
        {
            FingerCalibrations.insert(finger, WasdfCalibrationConfigurationFinger());
        }
    }
    QHash<Finger, WasdfCalibrationConfigurationFinger> FingerCalibrations;
};

#endif // WASDFCALIBRATIONCONFIGURATION_H
diff --git a/Projects/wasdf/src/lib/wasdfcalibrator.cpp b/Projects/wasdf/src/lib/wasdfcalibrator.cpp
index b42c7c9..f2ff118 100644
--- a/Projects/wasdf/src/lib/wasdfcalibrator.cpp
+++ b/Projects/wasdf/src/lib/wasdfcalibrator.cpp
@@ -1,9 +1,38 @@
#include "wasdfcalibrator.h"

#include <QTimer>
#include <QHashIterator>

#include "wasdf.h"

//need to write this somewhere to remember/understand it better: DURING calibration there's information pertaining to every pin (>= 10) on the arduino, but AFTER calibration we only want to emit/deliver information pertaining to exactly 10 pins. it's our job as the calibrator to figure out which 10. it is (was) slightly confusing that there are 2 sets of "configutations"
WasdfCalibrator::WasdfCalibrator(QObject *parent)
    : QObject(parent)
    , m_Timer(new QTimer(this))
    //, m_FingerCurrentlyBeingCalibrated(Finger0)
{
    m_Timer->setInterval(3000);
    m_Timer->setSingleShot(true);
    connect(m_Timer, &QTimer::timeout, this, &WasdfCalibrator::handleTimerTimedOut);
}
int WasdfCalibrator::getPinNumberWithTheFurthestAccumulatedDistanceTraveled()
{
    int currentPinIdWinning = 0;
    long accumulatedDistanceOfCurrentPinWinning = 0;
    QHashIterator<int /*pin number on arduino*/, PinCalibrationData> it(m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId);
    while(it.hasNext())
    {
        it.next();
        if(it.value().AccumulatedDistanceThePinHasMoved > accumulatedDistanceOfCurrentPinWinning)
        {
            currentPinIdWinning = it.key();
            accumulatedDistanceOfCurrentPinWinning = it.value().AccumulatedDistanceThePinHasMoved;
        }
    }
    //TODOreq: error checking? what if all pins didn't move at all for example, would likely mean the arduino is wired wrong
    return currentPinIdWinning;
}
#if 0
void WasdfCalibrator::calibrateNextFingerAndEmitCalibrationCompleteAfterLastFinger()
{
    if(m_CurrentFingerBeingCalibrated == Finger::Finger9)
@@ -14,7 +43,31 @@ void WasdfCalibrator::calibrateNextFingerAndEmitCalibrationCompleteAfterLastFing

    }
}
#endif
void WasdfCalibrator::handleAnalogPinReadingChanged(int pinNumberOnArduino, int newPinPosition)
{
    PinCalibrationData currentPinData = m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId.value(pinNumberOnArduino, PinCalibrationData());
    currentPinData.AccumulatedDistanceThePinHasMoved += static_cast<long>(abs(currentPinData.PreviousPinPosition - newPinPosition));
    m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId.insert(pinNumberOnArduino, currentPinData);
}
void WasdfCalibrator::startCalibrating()
{
    calibrateNextFingerAndEmitCalibrationCompleteAfterLastFinger();//calibrateNextFingerAndEmitCalibrationCompleteAfterLastFinger();
    emit o("Move your right index finger back and forth as far as much as you can and as far as you can for a few seconds."); //TODOreq: the wording here sucks, the user will be confused: "aren't as far and as much the same?"
    m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId.clear();
    m_Timer->start();
}
void WasdfCalibrator::handleTimerTimedOut()
{
    //pseudo: RightIndexFinger = m_FingerThatMovedTheMostTotalDistance;

    int pinNumberOfRightIndexFinger = getPinNumberWithTheFurthestAccumulatedDistanceTraveled();
    WasdfCalibrationFingerConfiguration fingerConfiguration = m_Calibration.value(Finger::RightIndex_Finger6, WasdfCalibrationFingerConfiguration());
    fingerConfiguration.AnalogPinIdOnArduino = pinNumberOfRightIndexFinger;
    //TODOreq: we should have min/max values at this point and should assign them to fingerConfiguration
    m_Calibration.insert(Finger::RightIndex_Finger6, fingerConfiguration);
    emit o("We've determined that your right index finger is connected to arduino's analog pin #" + QString::number(pinNumberOfRightIndexFinger));

    //TODreq: eventually:
    emit calibrationComplete(m_Calibration);
}
diff --git a/Projects/wasdf/src/lib/wasdfcalibrator.h b/Projects/wasdf/src/lib/wasdfcalibrator.h
index 7398d8e..dd6523d 100644
--- a/Projects/wasdf/src/lib/wasdfcalibrator.h
+++ b/Projects/wasdf/src/lib/wasdfcalibrator.h
@@ -3,8 +3,11 @@

#include <QObject>

#include <QHash>

#include "wasdf.h"

#include "wasdfcalibrationconfiguration.h"class QTimer;

class WasdfCalibrator : public QObject
{
@@ -12,14 +15,27 @@ class WasdfCalibrator : public QObject
public:
    explicit WasdfCalibrator(QObject *parent = 0);
private:
    voidstruct PinCalibrationData
    {
        int PreviousPinPosition = 0;
        long AccumulatedDistanceThePinHasMoved = 0;
    };

    //void calibrateNextFingerAndEmitCalibrationCompleteAfterLastFinger();
    int getPinNumberWithTheFurthestAccumulatedDistanceTraveled();

    FingerQHash<int /*pin number on arduino*/, PinCalibrationData> m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId;
    QTimer *m_Timer;
    //Finger m_FingerCurrentlyBeingCalibrated;
    WasdfCalibrationConfiguration m_Calibration;
signals:
    void o(const QString &msg);
    void calibrationComplete(const WasdfCalibrationConfiguration &calibrationConfiguration);
public slots:
    void handleAnalogPinReadingChanged(int pinNumberOnArduino, int newPinPosition);
    void startCalibrating();
private slots:
    void handleTimerTimedOut();
};

#endif // WASDFCALIBRATOR_H
diff --git a/Projects/wasdf/src/wasdf-cli.pro b/Projects/wasdf/src/wasdf-cli.pro
index c681b81..6674a4c 100644
--- a/Projects/wasdf/src/wasdf-cli.pro
+++ b/Projects/wasdf/src/wasdf-cli.pro
@@ -8,7 +8,7 @@ QT       += core serialport
QT       -= gui

TARGET = wasdf-cli
CONFIG   += console c++11
CONFIG   -= app_bundle

TEMPLATE = app
diff --git a/Projects/wasdf/src/wasdf.pri b/Projects/wasdf/src/wasdf.pri
index 9a24e7d..c387a3f 100644
--- a/Projects/wasdf/src/wasdf.pri
+++ b/Projects/wasdf/src/wasdf.pri
@@ -1,9 +1,8 @@
INCLUDEPATH *= $$system(pwd)/lib

HEADERS *= $$system(pwd)/lib/wasdf.h \
    lib/wasdfarduino.h$$system(pwd)/lib/wasdfarduino.h \
    lib/wasdfcalibrator.h \
    lib/wasdfcalibrationconfiguration.h$$system(pwd)/lib/wasdfcalibrator.h
SOURCES *= $$system(pwd)/lib/wasdf.cpp \
    lib/wasdfarduino.cpp$$system(pwd)/lib/wasdfarduino.cpp \
    lib/wasdfcalibrator.cpp$$system(pwd)/lib/wasdfcalibrator.cpp