From aff688bfe6b2b213a3621a050626b71c9d4e4b4c Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 11:46:35 -0500 Subject: [PATCH 01/11] add to domain data --- lib/core/src/OutputFile.cpp | 8 ++--- .../include/av-speech-in-noise/Model.hpp | 29 +++++++++++++++++-- test/OutputFile.cpp | 6 +++- test/RecognitionTestModel.cpp | 22 ++++++++++++++ 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/lib/core/src/OutputFile.cpp b/lib/core/src/OutputFile.cpp index d3727346..5c35dc55 100644 --- a/lib/core/src/OutputFile.cpp +++ b/lib/core/src/OutputFile.cpp @@ -204,13 +204,13 @@ static auto operator<<(std::ostream &stream, insertNewLine(stream); insert(stream, g.systemTime.microseconds); insertCommaAndSpace(stream); - insert(stream, g.left.x); + insert(stream, g.left.position.relativeScreen.x); insert(stream, " "); - insert(stream, g.left.y); + insert(stream, g.left.position.relativeScreen.y); insertCommaAndSpace(stream); - insert(stream, g.right.x); + insert(stream, g.right.position.relativeScreen.x); insert(stream, " "); - insert(stream, g.right.y); + insert(stream, g.right.position.relativeScreen.y); }); return insertNewLine(stream); } diff --git a/lib/domain/include/av-speech-in-noise/Model.hpp b/lib/domain/include/av-speech-in-noise/Model.hpp index 0914413e..ee903166 100644 --- a/lib/domain/include/av-speech-in-noise/Model.hpp +++ b/lib/domain/include/av-speech-in-noise/Model.hpp @@ -162,6 +162,31 @@ struct EyeGaze { float y; }; +struct Point2D { + float x; + float y; +}; + +struct Point3D { + float x; + float y; + float z; +}; + +struct GazeOrigin { + Point3D relativeTrackbox; +}; + +struct GazePosition { + Point3D relativeTrackbox; + Point2D relativeScreen; +}; + +struct Gaze { + GazeOrigin origin; + GazePosition position; +}; + struct EyeTrackerSystemTime { std::int_least64_t microseconds; }; @@ -177,8 +202,8 @@ struct EyeTrackerTargetPlayerSynchronization { struct BinocularGazeSample { EyeTrackerSystemTime systemTime; - EyeGaze left; - EyeGaze right; + Gaze left; + Gaze right; }; using BinocularGazeSamples = typename std::vector; diff --git a/test/OutputFile.cpp b/test/OutputFile.cpp index a76e0cba..eabac69a 100644 --- a/test/OutputFile.cpp +++ b/test/OutputFile.cpp @@ -670,7 +670,11 @@ class OutputFileTests : public ::testing::Test { std::vector left, std::vector right) { eyeGazes.resize(t.size()); std::generate(eyeGazes.begin(), eyeGazes.end(), [&, n = 0]() mutable { - BinocularGazeSample gazeSamples{{t.at(n)}, left.at(n), right.at(n)}; + BinocularGazeSample gazeSamples{{t.at(n)}, + Gaze{GazeOrigin{}, + GazePosition{{}, Point2D{left.at(n).x, left.at(n).y}}}, + Gaze{GazeOrigin{}, + GazePosition{{}, Point2D{right.at(n).x, right.at(n).y}}}}; ++n; return gazeSamples; }); diff --git a/test/RecognitionTestModel.cpp b/test/RecognitionTestModel.cpp index 01edf65d..e8170781 100644 --- a/test/RecognitionTestModel.cpp +++ b/test/RecognitionTestModel.cpp @@ -16,6 +16,28 @@ constexpr auto operator==(const EyeGaze &a, const EyeGaze &b) -> bool { return a.x == b.x && a.y == b.y; } +constexpr auto operator==(const Point2D &a, const Point2D &b) -> bool { + return a.x == b.x && a.y == b.y; +} + +constexpr auto operator==(const Point3D &a, const Point3D &b) -> bool { + return a.x == b.x && a.y == b.y && a.z == b.z; +} + +constexpr auto operator==(const GazeOrigin &a, const GazeOrigin &b) -> bool { + return a.relativeTrackbox == b.relativeTrackbox; +} + +constexpr auto operator==(const GazePosition &a, const GazePosition &b) + -> bool { + return a.relativeTrackbox == b.relativeTrackbox && + a.relativeScreen == b.relativeScreen; +} + +constexpr auto operator==(const Gaze &a, const Gaze &b) -> bool { + return a.origin == b.origin && a.position == b.position; +} + constexpr auto operator==( const BinocularGazeSample &a, const BinocularGazeSample &b) -> bool { return a.systemTime.microseconds == b.systemTime.microseconds && From 607ff6096587eaf124ac280ba9000846c20e592f Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 11:52:25 -0500 Subject: [PATCH 02/11] refactor --- test/RecognitionTestModel.cpp | 43 +++++++++-------------------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/test/RecognitionTestModel.cpp b/test/RecognitionTestModel.cpp index e8170781..31a18a7d 100644 --- a/test/RecognitionTestModel.cpp +++ b/test/RecognitionTestModel.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace av_speech_in_noise { @@ -283,10 +284,6 @@ class SubmittingCoordinateResponse : public UseCase { } }; -auto openSetAdaptiveTarget(OutputFileStub &file) -> std::string { - return file.openSetAdaptiveTrial().target; -} - class EyeTrackerStub : public EyeTracker { public: auto recordingTimeAllocatedSeconds() const -> double { @@ -355,8 +352,6 @@ class ClockStub : public Clock { return time_; } - void setTime(std::string s) { time_ = std::move(s); } - private: std::string time_; bool timeQueried_{}; @@ -424,7 +419,9 @@ void assertPlayed(MaskerPlayerStub &player) { AV_SPEECH_IN_NOISE_EXPECT_TRUE(player.played()); } -auto filePath(TargetPlayerStub &player) { return player.filePath(); } +auto filePath(TargetPlayerStub &player) -> std::string { + return player.filePath(); +} void assertFilePathEquals(TargetPlayerStub &player, const std::string &what) { AV_SPEECH_IN_NOISE_EXPECT_EQUAL(what, filePath(player)); @@ -434,7 +431,9 @@ void assertFilePathEquals(MaskerPlayerStub &player, const std::string &what) { AV_SPEECH_IN_NOISE_EXPECT_EQUAL(what, player.filePath()); } -auto secondsSeeked(MaskerPlayerStub &player) { return player.secondsSeeked(); } +auto secondsSeeked(MaskerPlayerStub &player) -> double { + return player.secondsSeeked(); +} void setFullScaleLevel_dB_SPL(Test &test, int x) { test.fullScaleLevel.dB_SPL = x; @@ -460,10 +459,6 @@ auto testComplete(RecognitionTestModelImpl &model) -> bool { return model.testComplete(); } -auto freeResponseTrial(OutputFileStub &file) { - return file.freeResponseTrial(); -} - void assertOnlyUsingFirstChannel(TargetPlayerStub &player) { AV_SPEECH_IN_NOISE_EXPECT_TRUE(player.usingFirstChannelOnly()); } @@ -689,23 +684,6 @@ class RecognitionTestModelTests : public ::testing::Test { assertFilePathEquals(targetPlayer, "a"); } - void assertWritesTarget(TargetWritingUseCase &useCase) { - evaluator.setFileName("a"); - run(useCase, model); - AV_SPEECH_IN_NOISE_EXPECT_EQUAL( - std::string{"a"}, useCase.target(outputFile)); - } - - void assertPassesCurrentTargetToEvaluatorBeforeAdvancingTarget( - UseCase &useCase) { - run(initializingTest, model); - setCurrentTarget(testMethod, "a"); - testMethod.setCurrentTargetWhenNextTarget("b"); - run(useCase, model); - AV_SPEECH_IN_NOISE_EXPECT_EQUAL( - std::string{"a"}, filePathForFileName(evaluator)); - } - void assertTestMethodLogContains( UseCase &useCase, const std::string &what) { run(initializingTest, model); @@ -1094,10 +1072,11 @@ RECOGNITION_TEST_MODEL_TEST(fadeOutCompleteStopsEyeTracker) { RECOGNITION_TEST_MODEL_TEST(submittingCoordinateResponseWritesEyeGazes) { run(initializingTestWithEyeTracking, model); - setEyeGazes(eyeTracker, {{{1}, {2, 3}, {4, 5}}, {{6}, {7, 8}, {9, 10}}}); + setEyeGazes( + eyeTracker, {{{1}, {{2, 3}}, {{4, 5}}}, {{6}, {{7, 8}}, {{9, 10}}}}); run(submittingCoordinateResponse, model); - ::assertEqual( - {{{1}, {2, 3}, {4, 5}}, {{6}, {7, 8}, {9, 10}}}, outputFile.eyeGazes()); + ::assertEqual({{{1}, {{2, 3}}, {{4, 5}}}, {{6}, {{7, 8}}, {{9, 10}}}}, + outputFile.eyeGazes()); } RECOGNITION_TEST_MODEL_TEST( From ab0f814454b2d6eb398914cd42ed0feaf02bfedd Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 11:55:22 -0500 Subject: [PATCH 03/11] scary refactoring --- test/RecognitionTestModel.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/RecognitionTestModel.cpp b/test/RecognitionTestModel.cpp index 31a18a7d..7fec0ef1 100644 --- a/test/RecognitionTestModel.cpp +++ b/test/RecognitionTestModel.cpp @@ -1072,10 +1072,12 @@ RECOGNITION_TEST_MODEL_TEST(fadeOutCompleteStopsEyeTracker) { RECOGNITION_TEST_MODEL_TEST(submittingCoordinateResponseWritesEyeGazes) { run(initializingTestWithEyeTracking, model); - setEyeGazes( - eyeTracker, {{{1}, {{2, 3}}, {{4, 5}}}, {{6}, {{7, 8}}, {{9, 10}}}}); + setEyeGazes(eyeTracker, + {{{1}, {{}, {{}, {2, 3}}}, {{}, {{}, {4, 5}}}}, + {{6}, {{}, {{}, {7, 8}}}, {{}, {{}, {9, 10}}}}}); run(submittingCoordinateResponse, model); - ::assertEqual({{{1}, {{2, 3}}, {{4, 5}}}, {{6}, {{7, 8}}, {{9, 10}}}}, + ::assertEqual({{{1}, {{}, {{}, {2, 3}}}, {{}, {{}, {4, 5}}}}, + {{6}, {{}, {{}, {7, 8}}}, {{}, {{}, {9, 10}}}}}, outputFile.eyeGazes()); } From da5747c1a9a9849e8c261473296066cdac13f522 Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 12:01:09 -0500 Subject: [PATCH 04/11] refactor --- .../include/av-speech-in-noise/core/OutputFile.hpp | 12 ++++++------ lib/core/src/OutputFile.cpp | 4 ++-- test/OutputFile.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/core/include/av-speech-in-noise/core/OutputFile.hpp b/lib/core/include/av-speech-in-noise/core/OutputFile.hpp index 4bb2322e..d55ee928 100644 --- a/lib/core/include/av-speech-in-noise/core/OutputFile.hpp +++ b/lib/core/include/av-speech-in-noise/core/OutputFile.hpp @@ -17,8 +17,8 @@ enum class HeadingItem { target, correctKeywords, freeResponse, - leftGaze, - rightGaze, + leftGazePositionRelativeScreen, + rightGazePositionRelativeScreen, eyeTrackerTime, targetPlayerTime, correctConsonant, @@ -57,10 +57,10 @@ constexpr auto name(HeadingItem i) -> const char * { return "response"; case HeadingItem::correctKeywords: return "# correct keywords"; - case HeadingItem::leftGaze: - return "left gaze [x y]"; - case HeadingItem::rightGaze: - return "right gaze [x y]"; + case HeadingItem::leftGazePositionRelativeScreen: + return "left gaze position relative screen [x y]"; + case HeadingItem::rightGazePositionRelativeScreen: + return "right gaze position relative screen [x y]"; case HeadingItem::eyeTrackerTime: return "eye tracker time (us)"; case HeadingItem::targetPlayerTime: diff --git a/lib/core/src/OutputFile.cpp b/lib/core/src/OutputFile.cpp index 5c35dc55..b7b399f3 100644 --- a/lib/core/src/OutputFile.cpp +++ b/lib/core/src/OutputFile.cpp @@ -197,9 +197,9 @@ static auto operator<<(std::ostream &stream, const BinocularGazeSamples &gazeSamples) -> std::ostream & { insert(stream, name(HeadingItem::eyeTrackerTime)); insertCommaAndSpace(stream); - insert(stream, name(HeadingItem::leftGaze)); + insert(stream, name(HeadingItem::leftGazePositionRelativeScreen)); insertCommaAndSpace(stream); - insert(stream, name(HeadingItem::rightGaze)); + insert(stream, name(HeadingItem::rightGazePositionRelativeScreen)); std::for_each(gazeSamples.begin(), gazeSamples.end(), [&](auto g) { insertNewLine(stream); insert(stream, g.systemTime.microseconds); diff --git a/test/OutputFile.cpp b/test/OutputFile.cpp index eabac69a..b31e3113 100644 --- a/test/OutputFile.cpp +++ b/test/OutputFile.cpp @@ -988,8 +988,10 @@ OUTPUT_FILE_TEST(writeEyeGazes) { write(file, eyeGazes); assertNthCommaDelimitedEntryOfLine( writer, HeadingItem::eyeTrackerTime, 1, 1); - assertNthCommaDelimitedEntryOfLine(writer, HeadingItem::leftGaze, 2, 1); - assertNthCommaDelimitedEntryOfLine(writer, HeadingItem::rightGaze, 3, 1); + assertNthCommaDelimitedEntryOfLine( + writer, HeadingItem::leftGazePositionRelativeScreen, 2, 1); + assertNthCommaDelimitedEntryOfLine( + writer, HeadingItem::rightGazePositionRelativeScreen, 3, 1); assertNthCommaDelimitedEntryOfLine(writer, "1", 1, 2); assertNthCommaDelimitedEntryOfLine(writer, "0.4 0.44", 2, 2); assertNthCommaDelimitedEntryOfLine(writer, "0.7 0.77", 3, 2); From ac166efacd4c0ed19c2eacc88236b2cc5bdd9697 Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 12:09:03 -0500 Subject: [PATCH 05/11] adding test --- .../av-speech-in-noise/core/OutputFile.hpp | 6 +++ lib/core/src/OutputFile.cpp | 4 ++ test/OutputFile.cpp | 37 +++++++++++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/core/include/av-speech-in-noise/core/OutputFile.hpp b/lib/core/include/av-speech-in-noise/core/OutputFile.hpp index d55ee928..ad40d9ca 100644 --- a/lib/core/include/av-speech-in-noise/core/OutputFile.hpp +++ b/lib/core/include/av-speech-in-noise/core/OutputFile.hpp @@ -19,6 +19,8 @@ enum class HeadingItem { freeResponse, leftGazePositionRelativeScreen, rightGazePositionRelativeScreen, + leftGazePositionRelativeTracker, + rightGazePositionRelativeTracker, eyeTrackerTime, targetPlayerTime, correctConsonant, @@ -61,6 +63,10 @@ constexpr auto name(HeadingItem i) -> const char * { return "left gaze position relative screen [x y]"; case HeadingItem::rightGazePositionRelativeScreen: return "right gaze position relative screen [x y]"; + case HeadingItem::leftGazePositionRelativeTracker: + return "left gaze position relative tracker [x y z]"; + case HeadingItem::rightGazePositionRelativeTracker: + return "right gaze position relative tracker [x y z]"; case HeadingItem::eyeTrackerTime: return "eye tracker time (us)"; case HeadingItem::targetPlayerTime: diff --git a/lib/core/src/OutputFile.cpp b/lib/core/src/OutputFile.cpp index b7b399f3..765d293b 100644 --- a/lib/core/src/OutputFile.cpp +++ b/lib/core/src/OutputFile.cpp @@ -200,6 +200,10 @@ static auto operator<<(std::ostream &stream, insert(stream, name(HeadingItem::leftGazePositionRelativeScreen)); insertCommaAndSpace(stream); insert(stream, name(HeadingItem::rightGazePositionRelativeScreen)); + insertCommaAndSpace(stream); + insert(stream, name(HeadingItem::leftGazePositionRelativeTracker)); + insertCommaAndSpace(stream); + insert(stream, name(HeadingItem::rightGazePositionRelativeTracker)); std::for_each(gazeSamples.begin(), gazeSamples.end(), [&](auto g) { insertNewLine(stream); insert(stream, g.systemTime.microseconds); diff --git a/test/OutputFile.cpp b/test/OutputFile.cpp index b31e3113..830c011c 100644 --- a/test/OutputFile.cpp +++ b/test/OutputFile.cpp @@ -666,8 +666,9 @@ class OutputFileTests : public ::testing::Test { assertHeadingAtLine(useCase, 3); } - void setEyeGazes(std::vector t, - std::vector left, std::vector right) { + void setGazePositionsRelativeScreenAndEyeTrackerTimes( + std::vector t, std::vector left, + std::vector right) { eyeGazes.resize(t.size()); std::generate(eyeGazes.begin(), eyeGazes.end(), [&, n = 0]() mutable { BinocularGazeSample gazeSamples{{t.at(n)}, @@ -982,8 +983,9 @@ OUTPUT_FILE_TEST(writeFixedLevelTestWithAuditoryOnlyCondition) { assertConditionNameWritten(writingFixedLevelTest, Condition::auditoryOnly); } -OUTPUT_FILE_TEST(writeEyeGazes) { - setEyeGazes({1, 2, 3}, {{0.4F, 0.44F}, {0.5F, 0.55F}, {0.6F, 0.66F}}, +OUTPUT_FILE_TEST(writeGazePositionsRelativeScreenAndEyeTrackerTime) { + setGazePositionsRelativeScreenAndEyeTrackerTimes({1, 2, 3}, + {{0.4F, 0.44F}, {0.5F, 0.55F}, {0.6F, 0.66F}}, {{0.7F, 0.77F}, {0.8F, 0.88F}, {0.9F, 0.99F}}); write(file, eyeGazes); assertNthCommaDelimitedEntryOfLine( @@ -1003,6 +1005,33 @@ OUTPUT_FILE_TEST(writeEyeGazes) { assertNthCommaDelimitedEntryOfLine(writer, "0.9 0.99", 3, 4); } +OUTPUT_FILE_TEST(writeGazePositionsRelativeTracker) { + std::vector left{}; + std::vector right{}; + eyeGazes.resize(left.size()); + std::generate(eyeGazes.begin(), eyeGazes.end(), [&, n = 0]() mutable { + BinocularGazeSample gazeSamples{{}, + Gaze{GazeOrigin{}, GazePosition{left.at(n), {}}}, + Gaze{GazeOrigin{}, GazePosition{right.at(n), {}}}}; + ++n; + return gazeSamples; + }); + write(file, eyeGazes); + assertNthCommaDelimitedEntryOfLine( + writer, HeadingItem::leftGazePositionRelativeTracker, 4, 1); + assertNthCommaDelimitedEntryOfLine( + writer, HeadingItem::rightGazePositionRelativeTracker, 5, 1); + // assertNthCommaDelimitedEntryOfLine(writer, "1", 1, 2); + // assertNthCommaDelimitedEntryOfLine(writer, "0.4 0.44", 2, 2); + // assertNthCommaDelimitedEntryOfLine(writer, "0.7 0.77", 3, 2); + // assertNthCommaDelimitedEntryOfLine(writer, "2", 1, 3); + // assertNthCommaDelimitedEntryOfLine(writer, "0.5 0.55", 2, 3); + // assertNthCommaDelimitedEntryOfLine(writer, "0.8 0.88", 3, 3); + // assertNthCommaDelimitedEntryOfLine(writer, "3", 1, 4); + // assertNthCommaDelimitedEntryOfLine(writer, "0.6 0.66", 2, 4); + // assertNthCommaDelimitedEntryOfLine(writer, "0.9 0.99", 3, 4); +} + OUTPUT_FILE_TEST(writeTargetStartTime) { writeTargetStartTimeNanoseconds(file, 1); assertContainsColonDelimitedEntry(writer, "target start time (ns)", "1"); From c281101233dad195d6d5b7aec36c300c2fae69bf Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 12:47:01 -0500 Subject: [PATCH 06/11] finish test --- lib/core/src/OutputFile.cpp | 33 +++++++++++++++++++++------------ test/OutputFile.cpp | 21 ++++++++++----------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/lib/core/src/OutputFile.cpp b/lib/core/src/OutputFile.cpp index 765d293b..77c96fe0 100644 --- a/lib/core/src/OutputFile.cpp +++ b/lib/core/src/OutputFile.cpp @@ -43,6 +43,10 @@ static auto operator<<(std::ostream &os, Syllable item) -> std::ostream & { return os << name(item); } +static auto operator<<(std::ostream &os, Point3D point) -> std::ostream & { + return os << point.x << ' ' << point.y << ' ' << point.z; +} + template auto insert(std::ostream &stream, T item) -> std::ostream & { return stream << item; @@ -204,18 +208,23 @@ static auto operator<<(std::ostream &stream, insert(stream, name(HeadingItem::leftGazePositionRelativeTracker)); insertCommaAndSpace(stream); insert(stream, name(HeadingItem::rightGazePositionRelativeTracker)); - std::for_each(gazeSamples.begin(), gazeSamples.end(), [&](auto g) { - insertNewLine(stream); - insert(stream, g.systemTime.microseconds); - insertCommaAndSpace(stream); - insert(stream, g.left.position.relativeScreen.x); - insert(stream, " "); - insert(stream, g.left.position.relativeScreen.y); - insertCommaAndSpace(stream); - insert(stream, g.right.position.relativeScreen.x); - insert(stream, " "); - insert(stream, g.right.position.relativeScreen.y); - }); + std::for_each(gazeSamples.begin(), gazeSamples.end(), + [&](const BinocularGazeSample &g) { + insertNewLine(stream); + insert(stream, g.systemTime.microseconds); + insertCommaAndSpace(stream); + insert(stream, g.left.position.relativeScreen.x); + insert(stream, " "); + insert(stream, g.left.position.relativeScreen.y); + insertCommaAndSpace(stream); + insert(stream, g.right.position.relativeScreen.x); + insert(stream, " "); + insert(stream, g.right.position.relativeScreen.y); + insertCommaAndSpace(stream); + insert(stream, g.left.position.relativeTrackbox); + insertCommaAndSpace(stream); + insert(stream, g.right.position.relativeTrackbox); + }); return insertNewLine(stream); } diff --git a/test/OutputFile.cpp b/test/OutputFile.cpp index 830c011c..b7e2bfc9 100644 --- a/test/OutputFile.cpp +++ b/test/OutputFile.cpp @@ -1006,8 +1006,10 @@ OUTPUT_FILE_TEST(writeGazePositionsRelativeScreenAndEyeTrackerTime) { } OUTPUT_FILE_TEST(writeGazePositionsRelativeTracker) { - std::vector left{}; - std::vector right{}; + std::vector left{ + {0.4F, 0.44F, 0.444F}, {0.5, 0.55F, 0.555F}, {0.6F, 0.66F, 0.666F}}; + std::vector right{ + {0.7F, 0.77F, 0.777F}, {0.8F, 0.88F, 0.888F}, {0.9F, 0.99F, 0.999F}}; eyeGazes.resize(left.size()); std::generate(eyeGazes.begin(), eyeGazes.end(), [&, n = 0]() mutable { BinocularGazeSample gazeSamples{{}, @@ -1021,15 +1023,12 @@ OUTPUT_FILE_TEST(writeGazePositionsRelativeTracker) { writer, HeadingItem::leftGazePositionRelativeTracker, 4, 1); assertNthCommaDelimitedEntryOfLine( writer, HeadingItem::rightGazePositionRelativeTracker, 5, 1); - // assertNthCommaDelimitedEntryOfLine(writer, "1", 1, 2); - // assertNthCommaDelimitedEntryOfLine(writer, "0.4 0.44", 2, 2); - // assertNthCommaDelimitedEntryOfLine(writer, "0.7 0.77", 3, 2); - // assertNthCommaDelimitedEntryOfLine(writer, "2", 1, 3); - // assertNthCommaDelimitedEntryOfLine(writer, "0.5 0.55", 2, 3); - // assertNthCommaDelimitedEntryOfLine(writer, "0.8 0.88", 3, 3); - // assertNthCommaDelimitedEntryOfLine(writer, "3", 1, 4); - // assertNthCommaDelimitedEntryOfLine(writer, "0.6 0.66", 2, 4); - // assertNthCommaDelimitedEntryOfLine(writer, "0.9 0.99", 3, 4); + assertNthCommaDelimitedEntryOfLine(writer, "0.4 0.44 0.444", 4, 2); + assertNthCommaDelimitedEntryOfLine(writer, "0.7 0.77 0.777", 5, 2); + assertNthCommaDelimitedEntryOfLine(writer, "0.5 0.55 0.555", 4, 3); + assertNthCommaDelimitedEntryOfLine(writer, "0.8 0.88 0.888", 5, 3); + assertNthCommaDelimitedEntryOfLine(writer, "0.6 0.66 0.666", 4, 4); + assertNthCommaDelimitedEntryOfLine(writer, "0.9 0.99 0.999", 5, 4); } OUTPUT_FILE_TEST(writeTargetStartTime) { From af9fd9637322b96b545d0e9f016fe22acaa965c4 Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 12:50:26 -0500 Subject: [PATCH 07/11] add test --- .../av-speech-in-noise/core/OutputFile.hpp | 6 +++++ lib/core/src/OutputFile.cpp | 8 ++++++ test/OutputFile.cpp | 25 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/lib/core/include/av-speech-in-noise/core/OutputFile.hpp b/lib/core/include/av-speech-in-noise/core/OutputFile.hpp index ad40d9ca..9666245e 100644 --- a/lib/core/include/av-speech-in-noise/core/OutputFile.hpp +++ b/lib/core/include/av-speech-in-noise/core/OutputFile.hpp @@ -21,6 +21,8 @@ enum class HeadingItem { rightGazePositionRelativeScreen, leftGazePositionRelativeTracker, rightGazePositionRelativeTracker, + leftGazeOriginRelativeTracker, + rightGazeOriginRelativeTracker, eyeTrackerTime, targetPlayerTime, correctConsonant, @@ -67,6 +69,10 @@ constexpr auto name(HeadingItem i) -> const char * { return "left gaze position relative tracker [x y z]"; case HeadingItem::rightGazePositionRelativeTracker: return "right gaze position relative tracker [x y z]"; + case HeadingItem::leftGazeOriginRelativeTracker: + return "left gaze origin relative tracker [x y z]"; + case HeadingItem::rightGazeOriginRelativeTracker: + return "right gaze origin relative tracker [x y z]"; case HeadingItem::eyeTrackerTime: return "eye tracker time (us)"; case HeadingItem::targetPlayerTime: diff --git a/lib/core/src/OutputFile.cpp b/lib/core/src/OutputFile.cpp index 77c96fe0..c157bd0a 100644 --- a/lib/core/src/OutputFile.cpp +++ b/lib/core/src/OutputFile.cpp @@ -208,6 +208,10 @@ static auto operator<<(std::ostream &stream, insert(stream, name(HeadingItem::leftGazePositionRelativeTracker)); insertCommaAndSpace(stream); insert(stream, name(HeadingItem::rightGazePositionRelativeTracker)); + insertCommaAndSpace(stream); + insert(stream, name(HeadingItem::leftGazeOriginRelativeTracker)); + insertCommaAndSpace(stream); + insert(stream, name(HeadingItem::rightGazeOriginRelativeTracker)); std::for_each(gazeSamples.begin(), gazeSamples.end(), [&](const BinocularGazeSample &g) { insertNewLine(stream); @@ -224,6 +228,10 @@ static auto operator<<(std::ostream &stream, insert(stream, g.left.position.relativeTrackbox); insertCommaAndSpace(stream); insert(stream, g.right.position.relativeTrackbox); + insertCommaAndSpace(stream); + insert(stream, g.left.origin.relativeTrackbox); + insertCommaAndSpace(stream); + insert(stream, g.right.origin.relativeTrackbox); }); return insertNewLine(stream); } diff --git a/test/OutputFile.cpp b/test/OutputFile.cpp index b7e2bfc9..3e2f56b8 100644 --- a/test/OutputFile.cpp +++ b/test/OutputFile.cpp @@ -1031,6 +1031,31 @@ OUTPUT_FILE_TEST(writeGazePositionsRelativeTracker) { assertNthCommaDelimitedEntryOfLine(writer, "0.9 0.99 0.999", 5, 4); } +OUTPUT_FILE_TEST(writeGazeOrigins) { + std::vector left{ + {0.4F, 0.44F, 0.444F}, {0.5, 0.55F, 0.555F}, {0.6F, 0.66F, 0.666F}}; + std::vector right{ + {0.7F, 0.77F, 0.777F}, {0.8F, 0.88F, 0.888F}, {0.9F, 0.99F, 0.999F}}; + eyeGazes.resize(left.size()); + std::generate(eyeGazes.begin(), eyeGazes.end(), [&, n = 0]() mutable { + BinocularGazeSample gazeSamples{{}, Gaze{GazeOrigin{left.at(n)}, {}}, + Gaze{GazeOrigin{right.at(n)}, {}}}; + ++n; + return gazeSamples; + }); + write(file, eyeGazes); + assertNthCommaDelimitedEntryOfLine( + writer, HeadingItem::leftGazeOriginRelativeTracker, 6, 1); + assertNthCommaDelimitedEntryOfLine( + writer, HeadingItem::rightGazeOriginRelativeTracker, 7, 1); + assertNthCommaDelimitedEntryOfLine(writer, "0.4 0.44 0.444", 6, 2); + assertNthCommaDelimitedEntryOfLine(writer, "0.7 0.77 0.777", 7, 2); + assertNthCommaDelimitedEntryOfLine(writer, "0.5 0.55 0.555", 6, 3); + assertNthCommaDelimitedEntryOfLine(writer, "0.8 0.88 0.888", 7, 3); + assertNthCommaDelimitedEntryOfLine(writer, "0.6 0.66 0.666", 6, 4); + assertNthCommaDelimitedEntryOfLine(writer, "0.9 0.99 0.999", 7, 4); +} + OUTPUT_FILE_TEST(writeTargetStartTime) { writeTargetStartTimeNanoseconds(file, 1); assertContainsColonDelimitedEntry(writer, "target start time (ns)", "1"); From e0371cd49fe2a47ed217334fcb995dcb040c48d1 Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 12:51:48 -0500 Subject: [PATCH 08/11] refactor --- lib/core/src/OutputFile.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/core/src/OutputFile.cpp b/lib/core/src/OutputFile.cpp index c157bd0a..5805a594 100644 --- a/lib/core/src/OutputFile.cpp +++ b/lib/core/src/OutputFile.cpp @@ -47,6 +47,10 @@ static auto operator<<(std::ostream &os, Point3D point) -> std::ostream & { return os << point.x << ' ' << point.y << ' ' << point.z; } +static auto operator<<(std::ostream &os, Point2D point) -> std::ostream & { + return os << point.x << ' ' << point.y; +} + template auto insert(std::ostream &stream, T item) -> std::ostream & { return stream << item; @@ -217,13 +221,9 @@ static auto operator<<(std::ostream &stream, insertNewLine(stream); insert(stream, g.systemTime.microseconds); insertCommaAndSpace(stream); - insert(stream, g.left.position.relativeScreen.x); - insert(stream, " "); - insert(stream, g.left.position.relativeScreen.y); + insert(stream, g.left.position.relativeScreen); insertCommaAndSpace(stream); - insert(stream, g.right.position.relativeScreen.x); - insert(stream, " "); - insert(stream, g.right.position.relativeScreen.y); + insert(stream, g.right.position.relativeScreen); insertCommaAndSpace(stream); insert(stream, g.left.position.relativeTrackbox); insertCommaAndSpace(stream); From 5078147a891692d77b1cf1b365711d5b5a75eb2f Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 13:15:56 -0500 Subject: [PATCH 09/11] add eye origin and track relative point to impl --- macos/TobiiProEyeTracker.cpp | 80 ++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/macos/TobiiProEyeTracker.cpp b/macos/TobiiProEyeTracker.cpp index 07948d8e..63a33dc9 100644 --- a/macos/TobiiProEyeTracker.cpp +++ b/macos/TobiiProEyeTracker.cpp @@ -72,53 +72,89 @@ static auto at(const std::vector &b, gsl::index i) return b.at(i); } -static auto eyeGaze(const TobiiResearchEyeData &d) +static auto gazePositionOnDisplayArea(const TobiiResearchEyeData &d) -> const TobiiResearchNormalizedPoint2D & { return d.gaze_point.position_on_display_area; } -static auto leftEyeGaze(const std::vector &gaze, - gsl::index i) -> const TobiiResearchNormalizedPoint2D & { - return eyeGaze(at(gaze, i).left_eye); +static auto leftGazePositionOnDisplayArea( + const std::vector &gaze, gsl::index i) + -> const TobiiResearchNormalizedPoint2D & { + return gazePositionOnDisplayArea(at(gaze, i).left_eye); } -static auto rightEyeGaze(const std::vector &gaze, - gsl::index i) -> const TobiiResearchNormalizedPoint2D & { - return eyeGaze(at(gaze, i).right_eye); +static auto rightGazePositionOnDisplayArea( + const std::vector &gaze, gsl::index i) + -> const TobiiResearchNormalizedPoint2D & { + return gazePositionOnDisplayArea(at(gaze, i).right_eye); } static auto x(const TobiiResearchNormalizedPoint2D &p) -> float { return p.x; } static auto y(const TobiiResearchNormalizedPoint2D &p) -> float { return p.y; } -static auto leftEyeGaze(std::vector &b, gsl::index i) - -> EyeGaze & { - return at(b, i).left; +static auto leftGazePositionRelativeScreen( + std::vector &b, gsl::index i) -> Point2D & { + return at(b, i).left.position.relativeScreen; } -static auto rightEyeGaze(BinocularGazeSamples &b, gsl::index i) -> EyeGaze & { - return at(b, i).right; +static auto rightGazePositionRelativeScreen( + BinocularGazeSamples &b, gsl::index i) -> Point2D & { + return at(b, i).right.position.relativeScreen; } -static auto x(EyeGaze &p) -> float & { return p.x; } +static auto x(Point2D &p) -> float & { return p.x; } -static auto y(EyeGaze &p) -> float & { return p.y; } +static auto y(Point2D &p) -> float & { return p.y; } static auto size(const std::vector &v) -> gsl::index { return v.size(); } auto TobiiProTracker::gazeSamples() -> BinocularGazeSamples { - BinocularGazeSamples gazeSamples_(head > 0 ? head - 1 : 0); - for (gsl::index i{0}; i < size(gazeSamples_); ++i) { - at(gazeSamples_, i).systemTime.microseconds = + BinocularGazeSamples gazeSamples(head > 0 ? head - 1 : 0); + for (gsl::index i{0}; i < size(gazeSamples); ++i) { + at(gazeSamples, i).systemTime.microseconds = at(gazeData, i).system_time_stamp; - x(leftEyeGaze(gazeSamples_, i)) = x(leftEyeGaze(gazeData, i)); - y(leftEyeGaze(gazeSamples_, i)) = y(leftEyeGaze(gazeData, i)); - x(rightEyeGaze(gazeSamples_, i)) = x(rightEyeGaze(gazeData, i)); - y(rightEyeGaze(gazeSamples_, i)) = y(rightEyeGaze(gazeData, i)); + x(leftGazePositionRelativeScreen(gazeSamples, i)) = + x(leftGazePositionOnDisplayArea(gazeData, i)); + y(leftGazePositionRelativeScreen(gazeSamples, i)) = + y(leftGazePositionOnDisplayArea(gazeData, i)); + x(rightGazePositionRelativeScreen(gazeSamples, i)) = + x(rightGazePositionOnDisplayArea(gazeData, i)); + y(rightGazePositionRelativeScreen(gazeSamples, i)) = + y(rightGazePositionOnDisplayArea(gazeData, i)); + + at(gazeSamples, i).left.position.relativeTrackbox.x = + at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates.x; + at(gazeSamples, i).left.position.relativeTrackbox.y = + at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates.y; + at(gazeSamples, i).left.position.relativeTrackbox.z = + at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates.z; + at(gazeSamples, i).right.position.relativeTrackbox.x = + at(gazeData, i).right_eye.gaze_point.position_in_user_coordinates.x; + at(gazeSamples, i).right.position.relativeTrackbox.y = + at(gazeData, i).right_eye.gaze_point.position_in_user_coordinates.y; + at(gazeSamples, i).right.position.relativeTrackbox.z = + at(gazeData, i).right_eye.gaze_point.position_in_user_coordinates.z; + + at(gazeSamples, i).left.origin.relativeTrackbox.x = + at(gazeData, i).left_eye.gaze_origin.position_in_user_coordinates.x; + at(gazeSamples, i).left.origin.relativeTrackbox.y = + at(gazeData, i).left_eye.gaze_origin.position_in_user_coordinates.y; + at(gazeSamples, i).left.origin.relativeTrackbox.z = + at(gazeData, i).left_eye.gaze_origin.position_in_user_coordinates.z; + at(gazeSamples, i).right.origin.relativeTrackbox.x = + at(gazeData, i) + .right_eye.gaze_origin.position_in_user_coordinates.x; + at(gazeSamples, i).right.origin.relativeTrackbox.y = + at(gazeData, i) + .right_eye.gaze_origin.position_in_user_coordinates.y; + at(gazeSamples, i).right.origin.relativeTrackbox.z = + at(gazeData, i) + .right_eye.gaze_origin.position_in_user_coordinates.z; } - return gazeSamples_; + return gazeSamples; } auto TobiiProTracker::currentSystemTime() -> EyeTrackerSystemTime { From 9954136f41c5f5c74b6d508728330af0e5397893 Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 14:42:03 -0500 Subject: [PATCH 10/11] refactor --- macos/TobiiProEyeTracker.cpp | 43 +++++++++++++----------------------- 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/macos/TobiiProEyeTracker.cpp b/macos/TobiiProEyeTracker.cpp index 63a33dc9..5edd17f1 100644 --- a/macos/TobiiProEyeTracker.cpp +++ b/macos/TobiiProEyeTracker.cpp @@ -111,6 +111,12 @@ static auto size(const std::vector &v) -> gsl::index { return v.size(); } +static void assign(Point3D &p, TobiiResearchPoint3D other) { + p.x = other.x; + p.y = other.y; + p.z = other.z; +} + auto TobiiProTracker::gazeSamples() -> BinocularGazeSamples { BinocularGazeSamples gazeSamples(head > 0 ? head - 1 : 0); for (gsl::index i{0}; i < size(gazeSamples); ++i) { @@ -125,34 +131,15 @@ auto TobiiProTracker::gazeSamples() -> BinocularGazeSamples { y(rightGazePositionRelativeScreen(gazeSamples, i)) = y(rightGazePositionOnDisplayArea(gazeData, i)); - at(gazeSamples, i).left.position.relativeTrackbox.x = - at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates.x; - at(gazeSamples, i).left.position.relativeTrackbox.y = - at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates.y; - at(gazeSamples, i).left.position.relativeTrackbox.z = - at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates.z; - at(gazeSamples, i).right.position.relativeTrackbox.x = - at(gazeData, i).right_eye.gaze_point.position_in_user_coordinates.x; - at(gazeSamples, i).right.position.relativeTrackbox.y = - at(gazeData, i).right_eye.gaze_point.position_in_user_coordinates.y; - at(gazeSamples, i).right.position.relativeTrackbox.z = - at(gazeData, i).right_eye.gaze_point.position_in_user_coordinates.z; - - at(gazeSamples, i).left.origin.relativeTrackbox.x = - at(gazeData, i).left_eye.gaze_origin.position_in_user_coordinates.x; - at(gazeSamples, i).left.origin.relativeTrackbox.y = - at(gazeData, i).left_eye.gaze_origin.position_in_user_coordinates.y; - at(gazeSamples, i).left.origin.relativeTrackbox.z = - at(gazeData, i).left_eye.gaze_origin.position_in_user_coordinates.z; - at(gazeSamples, i).right.origin.relativeTrackbox.x = - at(gazeData, i) - .right_eye.gaze_origin.position_in_user_coordinates.x; - at(gazeSamples, i).right.origin.relativeTrackbox.y = - at(gazeData, i) - .right_eye.gaze_origin.position_in_user_coordinates.y; - at(gazeSamples, i).right.origin.relativeTrackbox.z = - at(gazeData, i) - .right_eye.gaze_origin.position_in_user_coordinates.z; + assign(at(gazeSamples, i).left.position.relativeTrackbox, + at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates); + assign(at(gazeSamples, i).right.position.relativeTrackbox, + at(gazeData, i).right_eye.gaze_point.position_in_user_coordinates); + + assign(at(gazeSamples, i).left.origin.relativeTrackbox, + at(gazeData, i).left_eye.gaze_origin.position_in_user_coordinates); + assign(at(gazeSamples, i).right.origin.relativeTrackbox, + at(gazeData, i).right_eye.gaze_origin.position_in_user_coordinates); } return gazeSamples; } From 48eb0435bcde28fed7f5a789ce03a09b107d3456 Mon Sep 17 00:00:00 2001 From: Seth Bashford Date: Wed, 18 Aug 2021 14:48:31 -0500 Subject: [PATCH 11/11] refactor --- macos/TobiiProEyeTracker.cpp | 56 ++++++++++-------------------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/macos/TobiiProEyeTracker.cpp b/macos/TobiiProEyeTracker.cpp index 5edd17f1..bbcc3186 100644 --- a/macos/TobiiProEyeTracker.cpp +++ b/macos/TobiiProEyeTracker.cpp @@ -1,12 +1,15 @@ #include "TobiiProEyeTracker.hpp" -#include -#include -#include + #include #include #include +#include + +#include +#include + namespace av_speech_in_noise { static auto eyeTracker(TobiiResearchEyeTrackers *eyeTrackers) -> TobiiResearchEyeTracker * { @@ -77,36 +80,6 @@ static auto gazePositionOnDisplayArea(const TobiiResearchEyeData &d) return d.gaze_point.position_on_display_area; } -static auto leftGazePositionOnDisplayArea( - const std::vector &gaze, gsl::index i) - -> const TobiiResearchNormalizedPoint2D & { - return gazePositionOnDisplayArea(at(gaze, i).left_eye); -} - -static auto rightGazePositionOnDisplayArea( - const std::vector &gaze, gsl::index i) - -> const TobiiResearchNormalizedPoint2D & { - return gazePositionOnDisplayArea(at(gaze, i).right_eye); -} - -static auto x(const TobiiResearchNormalizedPoint2D &p) -> float { return p.x; } - -static auto y(const TobiiResearchNormalizedPoint2D &p) -> float { return p.y; } - -static auto leftGazePositionRelativeScreen( - std::vector &b, gsl::index i) -> Point2D & { - return at(b, i).left.position.relativeScreen; -} - -static auto rightGazePositionRelativeScreen( - BinocularGazeSamples &b, gsl::index i) -> Point2D & { - return at(b, i).right.position.relativeScreen; -} - -static auto x(Point2D &p) -> float & { return p.x; } - -static auto y(Point2D &p) -> float & { return p.y; } - static auto size(const std::vector &v) -> gsl::index { return v.size(); } @@ -117,19 +90,20 @@ static void assign(Point3D &p, TobiiResearchPoint3D other) { p.z = other.z; } +static void assign(Point2D &p, TobiiResearchNormalizedPoint2D other) { + p.x = other.x; + p.y = other.y; +} + auto TobiiProTracker::gazeSamples() -> BinocularGazeSamples { BinocularGazeSamples gazeSamples(head > 0 ? head - 1 : 0); for (gsl::index i{0}; i < size(gazeSamples); ++i) { at(gazeSamples, i).systemTime.microseconds = at(gazeData, i).system_time_stamp; - x(leftGazePositionRelativeScreen(gazeSamples, i)) = - x(leftGazePositionOnDisplayArea(gazeData, i)); - y(leftGazePositionRelativeScreen(gazeSamples, i)) = - y(leftGazePositionOnDisplayArea(gazeData, i)); - x(rightGazePositionRelativeScreen(gazeSamples, i)) = - x(rightGazePositionOnDisplayArea(gazeData, i)); - y(rightGazePositionRelativeScreen(gazeSamples, i)) = - y(rightGazePositionOnDisplayArea(gazeData, i)); + assign(at(gazeSamples, i).left.position.relativeScreen, + gazePositionOnDisplayArea(at(gazeData, i).left_eye)); + assign(at(gazeSamples, i).right.position.relativeScreen, + gazePositionOnDisplayArea(at(gazeData, i).right_eye)); assign(at(gazeSamples, i).left.position.relativeTrackbox, at(gazeData, i).left_eye.gaze_point.position_in_user_coordinates);