commit 0a1778ca6518d712b910ea8c8e4cba33ea9fc137
Author: d3fault <d3fault@d3fault.net>
Date:   Tue May 23 19:29:14 2017 -0700

    wasdf: add final pieces of "at rest" sensor value detection that happens transparently while calibrating fingers on the opposite hand. compiling and might work but tbh it's so complex I'm unsure

diff --git a/.lastModifiedTimestamps b/.lastModifiedTimestamps
index 4706369..46598c1 100644
--- a/.lastModifiedTimestamps
+++ b/.lastModifiedTimestamps
@@ -5899,20 +5899,20 @@ Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/Ma
Projects/wasdf/design/:1495255816
Projects/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/:1495590159Projects/wasdf/src/:1495592877
Projects/wasdf/src/cli/:1495395081
Projects/wasdf/src/cli/main.cpp:1495395081
Projects/wasdf/src/cli/wasdfcli.cpp:1495394570
Projects/wasdf/src/cli/wasdfcli.h:1495394574
Projects/wasdf/src/lib/:1495590034Projects/wasdf/src/lib/:1495592857
Projects/wasdf/src/lib/fingeriteratororderedbymostusedfingers.cpp:1495480054
Projects/wasdf/src/lib/fingeriteratororderedbymostusedfingers.h:1495480049
Projects/wasdf/src/lib/wasdf.cpp:1495494946
Projects/wasdf/src/lib/wasdf.h:1495585868Projects/wasdf/src/lib/wasdf.cpp:1495592670
Projects/wasdf/src/lib/wasdf.h:1495592478
Projects/wasdf/src/lib/wasdfarduino.cpp:1495494079
Projects/wasdf/src/lib/wasdfarduino.h:1495419683
Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp:1495590034
Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h:1495590011Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp:1495592857
Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h:1495591219
Projects/wasdf/src/lib/wasdfcalibrationconfigurationsettingsreaderwriter.cpp:1495562619
Projects/wasdf/src/lib/wasdfcalibrationconfigurationsettingsreaderwriter.h:1495490722
Projects/wasdf/src/lib/wasdfcalibrator.cpp:1495588873
diff --git a/Projects/wasdf/src/lib/wasdf.cpp b/Projects/wasdf/src/lib/wasdf.cpp
index 5843804..f88b336 100644
--- a/Projects/wasdf/src/lib/wasdf.cpp
+++ b/Projects/wasdf/src/lib/wasdf.cpp
@@ -20,6 +20,28 @@ Wasdf::Wasdf(QObject *parent)

    connect(m_Arduino, &WasdfArduino::e, this, &Wasdf::e);
}
bool Wasdf::fingerIsLeftHand(Finger finger)
{
    switch(finger)
    {
        case Finger::LeftPinky_Finger0:
        case Finger::LeftRing_Finger1:
        case Finger::LeftMiddle_Finger2:
        case Finger::LeftIndex_Finger3:
        case Finger::LeftThumb_Finger4:
            return true;
        break;

        case Finger::RightThumb_Finger5:
        case Finger::RightIndex_Finger6:
        case Finger::RightMiddle_Finger7:
        case Finger::RightRing_Finger8:
        case Finger::RightPinky_Finger9:
            return false;
        break;
    }
    return true; //shouldn't (won't) get here
}
void Wasdf::startWasdfActualSinceCalibrated()
{
    connect(m_Arduino, &WasdfArduino::fingerMoved, this, &Wasdf::handleFingerMoved);
@@ -110,3 +132,28 @@ QString fingerEnumToHumanReadableString(Finger finger)
    }
    return "#error finger#"; //should (will) never get here
}
bool WasdfCalibrationConfiguration::hasFingerWithAnalogPinId(int analogPinId) const
{
    QHashIterator<Finger, WasdfCalibrationFingerConfiguration> it(*this);
    while(it.hasNext())
    {
        it.next();
        if(it.value().AnalogPinIdOnArduino == analogPinId)
            return true;
    }
    return false;
}
Finger WasdfCalibrationConfiguration::getFingerByAnalogPinId(int analogPinId) const
{
    //NOTE: a finger with that analog pin id MUST exist or the program crashes xD. use hasFingerWithAnalogPinId() first

    QHashIterator<Finger, WasdfCalibrationFingerConfiguration> it(*this);
    while(it.hasNext())
    {
        it.next();
        if(it.value().AnalogPinIdOnArduino == analogPinId)
            return it.key();
    }
    qFatal("WasdfCalibrationConfiguration::getFingerByAnalogPinId called with invalid pinId. make sure it exists first by calling WasdfCalibrationConfiguration::hasFingerWithAnalogPinId");
    return Finger::Finger0_LeftPinky; //won't get here
}
diff --git a/Projects/wasdf/src/lib/wasdf.h b/Projects/wasdf/src/lib/wasdf.h
index b1bf5c1..66e293a 100644
--- a/Projects/wasdf/src/lib/wasdf.h
+++ b/Projects/wasdf/src/lib/wasdf.h
@@ -59,13 +59,19 @@ struct WasdfCalibrationFingerConfiguration
    //int AtRestMaxValue;
};

typedefclass WasdfCalibrationConfiguration : public QHash<Finger, WasdfCalibrationFingerConfiguration>
WasdfCalibrationConfiguration;{
public:
    bool hasFingerWithAnalogPinId(int analogPinId) const;
    Finger getFingerByAnalogPinId(int analogPinId) const;
};

class Wasdf : public QObject
{
    Q_OBJECT
public:
    explicit Wasdf(QObject *parent = 0);
    static bool fingerIsLeftHand(Finger finger);
private:
    void startWasdfActualSinceCalibrated();

diff --git a/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp
index edcdf7a..a94d51e 100644
--- a/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp
+++ b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp
@@ -6,7 +6,7 @@
//TODOmb: like I'm pushing this functionality into it's own class, so too should I (probably/maybe, but also maybe not [yet] if it's too much work to refactor xD) push the "analog pin detection" and "normal use range detection" into their own classes. Additionally, all calibration related classes should go in a ./calibration subfolder. The WasdfCalibrator should simply hasA these 3 types of calibration 'mode' thingies (for lack of a better word)
void WasdfCalibrationAtRestDetector::addAnalogPinPosition(int analogPinId, int newPinPosition)
{
    m_CurrentAllAnalogPinPositions_ByAnalogPinId.value(analogPinId, SharedPointerToListOfIntSensorValues(newSharedPointerToListOfIntAtRestValues(new QList<int /*sensor value*/>()))->append(newPinPosition);
}
void WasdfCalibrationAtRestDetector::weJustFinishedCalibratingThisAnalogPinId(Finger fingerWeJustFinishedCalibrating, int analogPinWeJustFinishedCalibrating)
{
@@ -16,12 +16,12 @@ void WasdfCalibrationAtRestDetector::weJustFinishedCalibratingThisAnalogPinId(Fi
    //now discard all position data for fingers on the same hand <---- NVM. although we know the finger that was just calibrated, we have no idea (yet) what finger the rest of them are (ok that's only partially true. as we get nearer and nearer to the last finger we know more and more fingers. still, simpler to discard "same hand" values at the very end in finalize, when we know ALL fingers)

    //1) average all the remaining at rest positions gathered in the last 5 seconds
    QHashIterator<int /*pin number on arduino*/, SharedPointerToListOfIntSensorValues>SharedPointerToListOfIntAtRestValues> it(m_CurrentAllAnalogPinPositions_ByAnalogPinId);
    while(it.hasNext())
    {
        it.next();
        int average = calculateAverage(*(it.value().data()));
        m_AveragedAtRestValuesGatheredWhileCalibratingFingers_ByFinger.value(fingerWeJustFinishedCalibrating, SharedPointerToListOf_PinNumbersAndSensorValues(new QList<PinNumberAndSensorValue>()))->append(PinNumberAndSensorValue(it.key(),SharedPointerToListOf_PinNumbersAndAtRestValues(new QList<PinNumberAndAtRestValue>()))->append(PinNumberAndAtRestValue(it.key(), average));
    }

    //2) clear the 'current' lists for the next 5 seconds of calibration (assuming there will be more, but it doesn't matter if there isn't)
@@ -32,31 +32,45 @@ void WasdfCalibrationAtRestDetector::finalize(WasdfCalibrationConfiguration *out
    //first discard all position data collected for fingers on the same hand
    //fuck, 'staggered' deletion of averages? fuck, my head hurts, what? like uhh when Finger6_RightIndex was being calibrated we delete the index 0 at rest average of the right hand, then Figner5_LeftIndex was being calibrated we delete the index 0 at rest average of the left hand, then Finger7_RightMiddle we delete index 1.. WAIT NO if we 'removed' index 0 (during RightIndex), then the new one we remove is going to be index 0 again!!! not 'staggered' after all. still my head hurts, typing this out certainly helps. so I use my ordered finger iterator I think. hmm I need to map the analog pins to the fingers first though, wait no that's already done in out_Calibration. wait no it IS staggered after all, since index 0 [now] points to an at rest value that we want to keep (one gathered while the opposite hand finger was being calibrated)! fuck, my head!!! still that just means a ++indexToDeleteOnRightHand and a ++indexToDeleteOnLeftHand, or something?
    //^hmmmm to make things easier for my head I could record which finger each set of "at rest" values corresponds to. Hmmmm QHash<Finger, QSharedPointer<QList> > atRestValues_ByFingerBeingCalibratedWhenTheyWereDetected ??? then I iterate that hash, map the analog pins to the fingers, determine if it's the same hand as in that QHash's key, drop that reading if it is, if it's opposite then add it to a newly built QHash<Finger, QSharedPointer<QList> >, then finally after that iteration of same-hand droppage, iterate the newly built hash simply to calculate the average rest value and THEN stuff it into out_Calibration
    //TODOreq: ^QHashIterator<Finger /*finger that was being calibrated when we gathered these averages*/, SharedPointerToListOf_PinNumbersAndAtRestValues> it0(m_AveragedAtRestValuesGatheredWhileCalibratingFingers_ByFinger);
    QHash<Finger, SharedPointerToListOfIntAtRestValues> atRestValuesOfFingersWithSameHandFingersRemoved_ByFinger;
    while(it0.hasNext())
    {
        it0.next();
        SharedPointerToListOf_PinNumbersAndAtRestValues listOfPinNumbersAndSensorValuesGatheredWhileCalibratingTheFingerKEY = it0.value();
        Q_FOREACH(const PinNumberAndAtRestValue &pinNumberAndAtRestValue, *(listOfPinNumbersAndSensorValuesGatheredWhileCalibratingTheFingerKEY.data()))
        {
            if(!out_Calibration->hasFingerWithAnalogPinId(pinNumberAndAtRestValue.PinNumber))
                continue; //the pin number might not correspond to a finger, like when that analog pin was not used

            Finger mappedFinger = out_Calibration->getFingerByAnalogPinId(pinNumberAndAtRestValue.PinNumber);
            if(Wasdf::fingerIsLeftHand(it0.key()) != Wasdf::fingerIsLeftHand(mappedFinger))
            {
                //mappedFinger is on the same hand as it0.key(), so we keep it's at rest value
                SharedPointerToListOfIntAtRestValues mappedFingersListOfAtRestValues = atRestValuesOfFingersWithSameHandFingersRemoved_ByFinger.value(mappedFinger, SharedPointerToListOfIntAtRestValues(new QList<int>()));
                mappedFingersListOfAtRestValues->append(pinNumberAndAtRestValue.AtRestValue);
            }
            //else: discard at rest values gathered on same hand as finger that was being calibrated at the time
        }
    }

#if 0 //TODOreq: merge the below with the above
    //get all the at rest readings for the fingers connected to analog pins we actually care about, then average those all together one last time, then stuff that final "at rest" value into the calibration
    QMutableHashIterator<Finger, WasdfCalibrationFingerConfiguration> it(*out_Calibration);
    while(it.hasNext())QHashIterator<Finger, SharedPointerToListOfIntAtRestValues> it1(atRestValuesOfFingersWithSameHandFingersRemoved_ByFinger);
    while(it1.hasNext())
    {
        it.next();it1.next();
        WasdfCalibrationFingerConfiguration fingerConfiguration = it.value();
        int analogPinId = fingerConfiguration.AnalogPinIdOnArduino;
        QSharedPointer<QList<QPair<int, int> > > atRestReadings = m_AveragedAtRestValuesGatheredWhileCalibratingFingers_ByFinger.value(analogPinId);
        int finalAveragedAtRestReading = calculateAverage(*(atRestReadings.data()));out_Calibration->value(it1.key());
        fingerConfiguration.AtRestPosition = finalAveragedAtRestReading;
        it.setValue(fingerConfiguration);calculateAverage(*(it1.value().data()));
        out_Calibration->insert(it1.key(), fingerConfiguration);
    }
#endif
}
int WasdfCalibrationAtRestDetector::calculateAverage(const QList<int> &numbersToAverageTogether)
{
    doubleqreal result = 0.0;
    Q_FOREACH(int currentNumber, numbersToAverageTogether)
    {
        result += currentNumber;
    }
    result /= static_cast<double>(numbersToAverageTogether.size());
    //TODOoptional: round, don't truncatestatic_cast<qreal>(numbersToAverageTogether.size());
    return static_cast<int>(result);qRound(result);
}
diff --git a/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h
index 501e252..a29fee6 100644
--- a/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h
+++ b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h
@@ -14,21 +14,21 @@ public:
    void weJustFinishedCalibratingThisAnalogPinId(Finger fingerWeJustFinishedCalibrating, int analogPinWeJustFinishedCalibrating);
    void finalize(WasdfCalibrationConfiguration *out_Calibration);
private:
    struct PinNumberAndSensorValuePinNumberAndAtRestValue
    {
        PinNumberAndSensorValue(intPinNumberAndAtRestValue(int pinNumber, int sensorValue)atRestValue)
            : PinNumber(pinNumber)
            , SensorValue(sensorValue)AtRestValue(atRestValue)
        { }
        int PinNumber;
        int SensorValue;AtRestValue;
    };
    typedef QSharedPointer<QList<int/*sensorQSharedPointer<QList<int/*at rest value*/> > SharedPointerToListOfIntSensorValues;SharedPointerToListOfIntAtRestValues;
    typedef QSharedPointer<QList<PinNumberAndSensorValue>QSharedPointer<QList<PinNumberAndAtRestValue> > SharedPointerToListOf_PinNumbersAndSensorValues;SharedPointerToListOf_PinNumbersAndAtRestValues;

    int calculateAverage(const QList<int> &numbersToAverageTogether);
    QHash<int /*pin number on arduino*/, SharedPointerToListOfIntSensorValues>SharedPointerToListOfIntAtRestValues> m_CurrentAllAnalogPinPositions_ByAnalogPinId;
    QHash<Finger /*finger that was being calibrated when we gathered these averages*/, SharedPointerToListOf_PinNumbersAndSensorValues>SharedPointerToListOf_PinNumbersAndAtRestValues> m_AveragedAtRestValuesGatheredWhileCalibratingFingers_ByFinger;
};

#endif // WASDFCALIBRATIONATRESTDETECTOR_H