commit 213af7197924cb9e7eb28d568515ef83408ff409
Author: d3fault <>
Date:   Tue May 23 17:57:29 2017 -0700

    wasdf: coded a large portion of "at rest" detection (done during calibration), but have yet to code the stuff necessary to ignore 'at rest' values read for fingers on the same hand as the finger currently being calibrated, as it's slightly complicated

diff --git a/.lastModifiedTimestamps b/.lastModifiedTimestamps
index f65109f..4f4cd36 100644
--- a/.lastModifiedTimestamps
+++ b/.lastModifiedTimestamps
@@ -44,7 +44,7 @@ Documents/minddump/2016/4/1459968855-LhX846.txt:1459969203
@@ -52,6 +52,7 @@ Documents/minddump/2017/5/1495326021-TJ3119.txt:1495326098
@@ -5898,24 +5899,26 @@ Projects/wasdf/assets/ArduinoSketches/ArduinoWriteChangesOnAnalogPinsToSerial/Ma
diff --git a/Documents/minddump/2017/5/1495582511-TJ1363.txt b/Documents/minddump/2017/5/1495582511-TJ1363.txt
new file mode 100644
index 0000000..66d4857
--- /dev/null
+++ b/Documents/minddump/2017/5/1495582511-TJ1363.txt
@@ -0,0 +1 @@
When you're russian, and I always find myself russian when I'm "on the clock", and employers tend to put pressure on their code monkeys because they want the most bang for their buck (they usually aren't aware of the "choose 2 of 3" thingy relating to code: good, fast, cheap)... err this sentence is hard to continue but anyways when I'm rushing I tend to NOT push separate pieces of functionality into their own class (like I should). It's only when I'm relaxed and coding at my own pace do I stop and think "hmm this isn't really related so I should make a class and hasA that class". When russian I tend to make giant monolithic classes that have assloads of special one-time-use member variables and methods and it's hard to decipher what's related to what. Fuck business-minded people.
diff --git a/Projects/wasdf/src/lib/wasdf.h b/Projects/wasdf/src/lib/wasdf.h
index 06895c1..b1bf5c1 100644
--- a/Projects/wasdf/src/lib/wasdf.h
+++ b/Projects/wasdf/src/lib/wasdf.h
@@ -52,8 +52,7 @@ struct WasdfCalibrationFingerConfiguration
    int MinValue = 1023; //TODOreq: ctrl+shift+f all non-comment instances of '1023' (and 0) and replace them all with a common constant declared at the top of this file
    int MaxValue = 0;

    //intint AtRestPosition; //we'd//TODOreq: we'd hardcode ~10% range around this AtRestPosition (until the AtRestMaxValue/AtRestMinValue is implemented, at which point percentages (or this mid-point) are no longer used). also worth noting that the range min/max calulcated using percentages must be constrained to 0-1023

    //int AtRestMinValue;
diff --git a/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp
new file mode 100644
index 0000000..ce4421c
--- /dev/null
+++ b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.cpp
@@ -0,0 +1,59 @@
???#include "wasdfcalibrationatrestdetector.h"

#include <QHashIterator>
#include <QMutableHashIterator>

//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, QSharedPointer<QList<int> >(new QList<int /*sensor value*/>()))->append(newPinPosition);
void WasdfCalibrationAtRestDetector::weJustFinishedCalibratingThisAnalogPinId(int analogPinIdToDiscardCurrentPinPositionsFor)
    //0) discard the positions for the analog pin id passed in (because we told the user to move it a bunch, so it wasn't "at rest" at all!)

    //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*/, QSharedPointer<QList<int /*sensor value*/> > > it(m_CurrentAllAnalogPinPositions_ByAnalogPinId);
        int average = calculateAverage(*(it.value().data()));
        m_RunningAllAnalogPinsAtRestPositionsToBeAveragedYetAgainAtTheVeryEndOfCalibration_ByAnalogPinId.value(it.key(), QSharedPointer<QList<int> >(new QList<int>()))->append(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)
void WasdfCalibrationAtRestDetector::finalize(WasdfCalibrationConfiguration *out_Calibration)
    //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 droppage, iterate the newly built one simply to calculate the average rest value and THEN stuff it into out_Calibration
    //TODOreq: ^

    //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);
        WasdfCalibrationFingerConfiguration fingerConfiguration = it.value();
        int analogPinId = fingerConfiguration.AnalogPinIdOnArduino;
        QSharedPointer<QList<int> > atRestReadings = m_RunningAllAnalogPinsAtRestPositionsToBeAveragedYetAgainAtTheVeryEndOfCalibration_ByAnalogPinId.value(analogPinId);
        int finalAveragedAtRestReading = calculateAverage(*(;
        fingerConfiguration.AtRestPosition = finalAveragedAtRestReading;
int WasdfCalibrationAtRestDetector::calculateAverage(const QList<int> &numbersToAverageTogether)
    double result = 0.0;
    Q_FOREACH(int currentNumber, numbersToAverageTogether)
        result += currentNumber;
    result /= static_cast<double>(numbersToAverageTogether.size());
    //TODOoptional: round, don't truncate
    return static_cast<int>(result);
diff --git a/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h
new file mode 100644
index 0000000..8fd3279
--- /dev/null
+++ b/Projects/wasdf/src/lib/wasdfcalibrationatrestdetector.h
@@ -0,0 +1,22 @@

#include <QHash>
#include <QList>
#include <QSharedPointer>

#include "wasdf.h"

class WasdfCalibrationAtRestDetector
    void addAnalogPinPosition(int analogPinId, int newPinPosition);
    void weJustFinishedCalibratingThisAnalogPinId(int analogPinIdToDiscardCurrentPinPositionsFor);
    void finalize(WasdfCalibrationConfiguration *out_Calibration);
    int calculateAverage(const QList<int> &numbersToAverageTogether);
    QHash<int /*pin number on arduino*/, QSharedPointer<QList<int/*sensor value*/> > > m_CurrentAllAnalogPinPositions_ByAnalogPinId;
    QHash<int /*pin number on arduino*/, QSharedPointer<QList<int/*sensor value*/> > > m_RunningAllAnalogPinsAtRestPositionsToBeAveragedYetAgainAtTheVeryEndOfCalibration_ByAnalogPinId;

diff --git a/Projects/wasdf/src/lib/wasdfcalibrator.cpp b/Projects/wasdf/src/lib/wasdfcalibrator.cpp
index 34d4bb8..8ef7594 100644
--- a/Projects/wasdf/src/lib/wasdfcalibrator.cpp
+++ b/Projects/wasdf/src/lib/wasdfcalibrator.cpp
@@ -9,6 +9,7 @@
//need to write this somewhere to remember/understand it better: DURING calibration there's information pertaining to every pin (>= 10) on the arduino, but ONCE CALIBRATED 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"
//TODOreq: "at rest" detection/calibration, which should be a RANGE of motion where we ignore. it needn't be hugging the extremeties (0 or 1023), can be right smack in the middle. that range-size should initially be a hardcoded percentage (10%?) of their full 0-1023 utilization, but longer term would be nice if they could specify their own range-size during the calibration phase
//^"at rest" detection could be done after all 10 fingers are calibrated ("ok now put your fingers at rest and keep them still for 5 seconds"), or (ideally) we could do it on the fly while doing the initial 10 finger calibration (the less steps to calibration, the better). to do it "on the fly" requires careful logic: I should detect the "at rest" point (which the at rest 'range' is based around) for a finger on my right hand while a finger on my left hand is being pin-detected-and-full-movement-range-calibrated (aka normal calibration). the reason for this is that fingers on the same hand tend to bend alongside other ones (whereas fingers on the opposite don't). an example flow: while calibrating left index finger, do at rest detection of right index finger; while calibrating right middle finger, do at rest detection of left index finger, so on and so forth. I'm not quite sure when the at rest detection of the very last finger (left pinky) should be done, but there's bound to be sometime to do it eventually~. maybe during the "ok now choose which finger you want as your ok/next/continue/yes finger?" stage (which, if it even exists (right index finger for now)) follows immediately after the calibration stage.
//^^I thought long and hard about it, and finally found a design I like that isn't toooooo complex and also doesn't require special handling of the last finger (left pinky). Basically WHILE we're doing analog pin detection and [normal use] range calibratioin we can be analyzing all of the ANALOG PINS (had:fingers) that aren't currently being calibrated for their "at rest" state. We basically just collect as much data as we can and then make sense of the data after the last finger has been calibrated. It doesn't matter that we don't know which finger each analog pin belongs to, because when we finally do "make sense of the data" we can then match up the analog pins to the fingers (and discard data for analog pins that don't have a finger now mapped). I do still want to only use "at rest" values that were collected while calibrating a fingers on the OPPOSITE hand, so really that's just dropping a couple data sets (once we know which analog pins map to each finger), no problem. Ultimately we'd get (or have remaining) 5 "at rest" values per finger, which we can average together I guess (but hey each of those 5 "at rest" values will themselves probably be averages of the ranges used for the 5 _seconds_ of calibration (happening on the opposite hand))
WasdfCalibrator::WasdfCalibrator(QObject *parent)
    : QObject(parent)
    , m_Timer(new QTimer(this))
@@ -19,31 +20,35 @@ WasdfCalibrator::WasdfCalibrator(QObject *parent)
WasdfCalibrator::PinNumDetectionAndCalibrationData WasdfCalibrator::getPinCalibrationDataWithTheFurthestAccumulatedDistanceTraveled()
    PinNumDetectionAndCalibrationData currentPinDataWinning;currentPinDataWithFurthestAccumulatedDistance;
    QHashIterator<int /*pin number on arduino*/, PinNumDetectionAndCalibrationData> it(m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId);
        if(it.value().AccumulatedDistanceThePinHasMoved > currentPinDataWinning.AccumulatedDistanceThePinHasMoved)currentPinDataWithFurthestAccumulatedDistance.AccumulatedDistanceThePinHasMoved)
            currentPinDataWinningcurrentPinDataWithFurthestAccumulatedDistance = it.value();
    //TODOreq: error checking? what if all pins didn't move at all for example, would likely mean the arduino is wired wrong
    return currentPinDataWinning;currentPinDataWithFurthestAccumulatedDistance;
void WasdfCalibrator::calibrateNextFingerAndEmitCalibrationCompleteAfterLastFinger()
        emit calibrationComplete(m_Calibration);
void WasdfCalibrator::calibrateFingerAndThenCallCalibrateNextFingerAgain(Finger fingerToCalibrate)
    m_FingerCurrentlyBeingCalibrated = fingerToCalibrate;
    emit o("Move your right index" + fingerEnumToHumanReadableString(fingerToCalibrate) + " finger back and forth as much as you can and as far as you can for a few seconds.");seconds. Try to keep your other fingers as still as possible (but in a position you find comfortable and natural)."); //TODOreq: the wording here sucks, the user will be confused: "aren't as far and as much the same?" an animated .gif explaining it to the user would be best, but even that gif needs to have carefully selected wording xD
    //TODOreq: ^ "left/right thumb finger" sounds dumb kek. there are probably other usages of that dumb-ness ofc. the solution is ez but busy work
void WasdfCalibrator::handleAnalogPinReadingChanged(int pinNumberOnArduino, int newPinPosition)
@@ -58,6 +63,9 @@ void WasdfCalibrator::handleAnalogPinReadingChanged(int pinNumberOnArduino, int
    currentPinData.PinCalibrationData.MaxValue = qMax(currentPinData.PinCalibrationData.MaxValue, newPinPosition);
    currentPinData.PinCalibrationData.MinValue = qMin(currentPinData.PinCalibrationData.MinValue, newPinPosition);

    //this line of code is to facilitate finger "at rest" position calibration
    m_AtRestDetector.addAnalogPinPosition(pinNumberOnArduino, newPinPosition);

    m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId.insert(pinNumberOnArduino, currentPinData);
void WasdfCalibrator::startCalibrating()
@@ -69,8 +77,12 @@ void WasdfCalibrator::handleTimerTimedOut()
    //pseudo: m_FingerCurrentlyBeingCalibrated = m_FingerThatMovedTheMostTotalDistance;

    PinNumDetectionAndCalibrationData pinCalibrationDataOfRightIndexFingerpinCalibrationDataOfFingerCurrentlyBeingCalibrated = getPinCalibrationDataWithTheFurthestAccumulatedDistanceTraveled();


    m_Calibration.insert(m_FingerCurrentlyBeingCalibrated, pinCalibrationDataOfRightIndexFinger.PinCalibrationData);pinCalibrationDataOfFingerCurrentlyBeingCalibrated.PinCalibrationData);

    emit o("We've determined that your " + fingerEnumToHumanReadableString(m_FingerCurrentlyBeingCalibrated) + " finger is connected to arduino's analog pin #" + QString::number(pinCalibrationDataOfRightIndexFinger.PinCalibrationData.AnalogPinIdOnArduino));QString::number(pinCalibrationDataOfFingerCurrentlyBeingCalibrated.PinCalibrationData.AnalogPinIdOnArduino));
diff --git a/Projects/wasdf/src/lib/wasdfcalibrator.h b/Projects/wasdf/src/lib/wasdfcalibrator.h
index 4182f49..f4b34d8 100644
--- a/Projects/wasdf/src/lib/wasdfcalibrator.h
+++ b/Projects/wasdf/src/lib/wasdfcalibrator.h
@@ -7,6 +7,7 @@

#include "wasdf.h"
#include "fingeriteratororderedbymostusedfingers.h"
#include "wasdfcalibrationatrestdetector.h"

class QTimer;

@@ -30,11 +31,12 @@ private:
    void calibrateFingerAndThenCallCalibrateNextFingerAgain(Finger fingerToCalibrate);
    PinNumDetectionAndCalibrationData getPinCalibrationDataWithTheFurthestAccumulatedDistanceTraveled();

    WasdfCalibrationConfiguration m_Calibration;
    QHash<int /*pin number on arduino*/, PinNumDetectionAndCalibrationData> m_AccumulatedDistancesEachAnalogPinMoved_ByAnalogPinId;
    QTimer *m_Timer;
    FingerIteratorOrderedByMostUsedFingers m_OrderedFingerIterator;
    Finger m_FingerCurrentlyBeingCalibrated;
    WasdfCalibrationConfiguration m_Calibration;WasdfCalibrationAtRestDetector m_AtRestDetector;
    void o(const QString &msg);
    void calibrationComplete(const WasdfCalibrationConfiguration &calibrationConfiguration);
diff --git a/Projects/wasdf/src/wasdf.pri b/Projects/wasdf/src/wasdf.pri
index d7d55d8..5f6bf95 100644
--- a/Projects/wasdf/src/wasdf.pri
+++ b/Projects/wasdf/src/wasdf.pri
@@ -4,9 +4,11 @@ HEADERS *= $$system(pwd)/lib/wasdf.h \
    $$system(pwd)/lib/wasdfarduino.h \
    $$system(pwd)/lib/wasdfcalibrator.h \
    $$system(pwd)/lib/fingeriteratororderedbymostusedfingers.h \
    $$system(pwd)/lib/wasdfcalibrationconfigurationsettingsreaderwriter.h \
SOURCES *= $$system(pwd)/lib/wasdf.cpp \
    $$system(pwd)/lib/wasdfarduino.cpp \
    $$system(pwd)/lib/wasdfcalibrator.cpp \
    $$system(pwd)/lib/fingeriteratororderedbymostusedfingers.cpp \
    $$system(pwd)/lib/wasdfcalibrationconfigurationsettingsreaderwriter.cpp \