diff --git a/bin/data/inFORM-escher-mode.mp4 b/bin/data/inFORM-escher-mode.mp4 new file mode 100755 index 0000000..839ecd1 Binary files /dev/null and b/bin/data/inFORM-escher-mode.mp4 differ diff --git a/neoForm.xcodeproj/project.pbxproj b/neoForm.xcodeproj/project.pbxproj index cf198d8..2c55691 100644 --- a/neoForm.xcodeproj/project.pbxproj +++ b/neoForm.xcodeproj/project.pbxproj @@ -56,6 +56,7 @@ A7A38C1DAA6949FC9F8B48C0 /* will_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = 98278F7AD1AA612A8F4DDA10 /* will_mosq.c */; }; ACE7DC9A3223ED5EE1B80074 /* cameras.c in Sources */ = {isa = PBXBuildFile; fileRef = 3DBD37876A11E46E4D7069B3 /* cameras.c */; }; B006626C26FF99AB717C7CD4 /* utf8_mosq.c in Sources */ = {isa = PBXBuildFile; fileRef = D1822FF66A31138F103D3C2F /* utf8_mosq.c */; }; + B94766EA2C3105CC00877064 /* InFormIOManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B94766E82C3105CC00877064 /* InFormIOManager.cpp */; }; B9A9F318297DF82000ACC2F8 /* KinectManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B9A9F2F5297DF82000ACC2F8 /* KinectManager.cpp */; }; B9A9F319297DF82000ACC2F8 /* SerialIOManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B9A9F2FA297DF82000ACC2F8 /* SerialIOManager.cpp */; }; B9A9F31A297DF82000ACC2F8 /* ShapeIOManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B9A9F2FD297DF82000ACC2F8 /* ShapeIOManager.cpp */; }; @@ -511,6 +512,8 @@ B88A80AA34B79BD6DA9253DE /* sse_utils.hpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = sse_utils.hpp; path = ../../../addons/ofxOpenCv/libs/opencv/include/opencv4/opencv2/core/sse_utils.hpp; sourceTree = SOURCE_ROOT; }; B8A2CBF3E24E6E5026B13A90 /* ofxBase3DVideo.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ofxBase3DVideo.h; path = ../../../addons/ofxKinect/src/ofxBase3DVideo.h; sourceTree = SOURCE_ROOT; }; B8F39F6EBA0607ECB7D18D89 /* handle_disconnect.c */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.c; fileEncoding = 4; name = handle_disconnect.c; path = "../../../addons/ofxMQTT-1.5.0/libs/mosquitto/src/handle_disconnect.c"; sourceTree = SOURCE_ROOT; }; + B94766E82C3105CC00877064 /* InFormIOManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InFormIOManager.cpp; sourceTree = ""; }; + B94766E92C3105CC00877064 /* InFormIOManager.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = InFormIOManager.hpp; sourceTree = ""; }; B9A9F2F5297DF82000ACC2F8 /* KinectManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KinectManager.cpp; sourceTree = ""; }; B9A9F2F6297DF82000ACC2F8 /* KinectManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = KinectManager.hpp; sourceTree = ""; }; B9A9F2F8297DF82000ACC2F8 /* PinConfigs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PinConfigs.h; sourceTree = ""; }; @@ -1980,15 +1983,17 @@ isa = PBXGroup; children = ( B9A9F2F8297DF82000ACC2F8 /* PinConfigs.h */, - B9A9F2F9297DF82000ACC2F8 /* TransformIOManager.hpp */, + B94766E82C3105CC00877064 /* InFormIOManager.cpp */, + B94766E92C3105CC00877064 /* InFormIOManager.hpp */, + B9A9F2FE297DF82000ACC2F8 /* SerialIOManager.hpp */, B9A9F2FA297DF82000ACC2F8 /* SerialIOManager.cpp */, B9A9F2FB297DF82000ACC2F8 /* SerialShapeIO.hpp */, - B9A9F2FC297DF82000ACC2F8 /* SerialShapeIOManager.hpp */, - B9A9F2FD297DF82000ACC2F8 /* ShapeIOManager.cpp */, - B9A9F2FE297DF82000ACC2F8 /* SerialIOManager.hpp */, B9A9F2FF297DF82000ACC2F8 /* SerialShapeIO.cpp */, + B9A9F2FC297DF82000ACC2F8 /* SerialShapeIOManager.hpp */, B9A9F300297DF82000ACC2F8 /* SerialShapeIOManager.cpp */, B9A9F301297DF82000ACC2F8 /* ShapeIOManager.hpp */, + B9A9F2FD297DF82000ACC2F8 /* ShapeIOManager.cpp */, + B9A9F2F9297DF82000ACC2F8 /* TransformIOManager.hpp */, B9A9F302297DF82000ACC2F8 /* TransformIOManager.cpp */, ); path = ShapeDisplayManagers; @@ -2007,15 +2012,15 @@ isa = PBXGroup; children = ( B9A9F308297DF82000ACC2F8 /* Application.hpp */, + B9A9F30E297DF82000ACC2F8 /* Application.cpp */, + B9A9F30F297DF82000ACC2F8 /* AxisChecker.hpp */, B9A9F309297DF82000ACC2F8 /* AxisChecker.cpp */, - B9A9F30A297DF82000ACC2F8 /* MqttTransmissionApp.cpp */, - B9A9F30B297DF82000ACC2F8 /* VideoPlayerApp.cpp */, B9A9F30C297DF82000ACC2F8 /* MqttTransmissionApp.hpp */, + B9A9F30A297DF82000ACC2F8 /* MqttTransmissionApp.cpp */, B9A9F30D297DF82000ACC2F8 /* VideoPlayerApp.hpp */, - B9A9F30E297DF82000ACC2F8 /* Application.cpp */, - B9A9F30F297DF82000ACC2F8 /* AxisChecker.hpp */, - 84B1DCFE2B792D8500DE7B7B /* KinectHandWavy.cpp */, + B9A9F30B297DF82000ACC2F8 /* VideoPlayerApp.cpp */, 84B1DCFF2B792D8500DE7B7B /* KinectHandWavy.hpp */, + 84B1DCFE2B792D8500DE7B7B /* KinectHandWavy.cpp */, B9A9F310297DF82000ACC2F8 /* DebuggingApps */, ); path = Applications; @@ -2024,12 +2029,12 @@ B9A9F310297DF82000ACC2F8 /* DebuggingApps */ = { isa = PBXGroup; children = ( - B9A9F311297DF82000ACC2F8 /* KinectDebugApp.cpp */, B9A9F312297DF82000ACC2F8 /* AxisCheckerApp.hpp */, - B9A9F313297DF82000ACC2F8 /* KinectDebugApp.hpp */, B9A9F314297DF82000ACC2F8 /* AxisCheckerApp.cpp */, - 84AEEE272A926C7700D26E7C /* DepthDebugApp.cpp */, 84AEEE282A926C7700D26E7C /* DepthDebugApp.hpp */, + 84AEEE272A926C7700D26E7C /* DepthDebugApp.cpp */, + B9A9F311297DF82000ACC2F8 /* KinectDebugApp.cpp */, + B9A9F313297DF82000ACC2F8 /* KinectDebugApp.hpp */, ); path = DebuggingApps; sourceTree = ""; @@ -2638,7 +2643,7 @@ attributes = { LastUpgradeCheck = 1420; }; - buildConfigurationList = E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "neoFORM" */; + buildConfigurationList = E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "neoForm" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; @@ -2713,6 +2718,7 @@ F4135EEFC911E9ED211FB6F9 /* core.c in Sources */, E55DEEF784A10419E444669E /* flags.c in Sources */, B9A9F31F297DF82000ACC2F8 /* AxisChecker.cpp in Sources */, + B94766EA2C3105CC00877064 /* InFormIOManager.cpp in Sources */, FCC16AB16073FF0581F50ED7 /* loader.c in Sources */, D31F5C1B140C59B2AF1533A8 /* registration.c in Sources */, 49BEEB2DFA5319D55AA6899F /* tilt.c in Sources */, @@ -3647,7 +3653,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "neoFORM" */ = { + E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "neoForm" */ = { isa = XCConfigurationList; buildConfigurations = ( E4B69B4E0A3A1720003C02F2 /* Debug */, diff --git a/src/AppManager.cpp b/src/AppManager.cpp index 470f584..16efba8 100644 --- a/src/AppManager.cpp +++ b/src/AppManager.cpp @@ -28,27 +28,22 @@ void AppManager::setup(){ timeOfLastUpdate = elapsedTimeInSeconds(); // set up applications - mqttApp = new MqttTransmissionApp(); - mqttApp->setRefForShapeIOManager(m_serialShapeIOManager); + mqttApp = new MqttTransmissionApp(m_serialShapeIOManager); applications["mqttTransmission"] = mqttApp; - videoPlayerApp = new VideoPlayerApp(); - videoPlayerApp->setRefForShapeIOManager(m_serialShapeIOManager); + videoPlayerApp = new VideoPlayerApp(m_serialShapeIOManager); applications["videoPlayer"] = videoPlayerApp; videoPlayerApp->setup(); // set up debugging application // and the debugging apps, too - axisCheckerApp = new AxisCheckerApp(); - axisCheckerApp->setRefForShapeIOManager(m_serialShapeIOManager); + axisCheckerApp = new AxisCheckerApp(m_serialShapeIOManager); applications["axisChecker"] = axisCheckerApp; - kinectDebugApp = new KinectDebugApp(kinectManager); - kinectDebugApp->setRefForShapeIOManager(m_serialShapeIOManager); + kinectDebugApp = new KinectDebugApp(m_serialShapeIOManager, kinectManager); applications["kinectDebug"] = kinectDebugApp; - depthDebugApp = new DepthDebugApp(); - depthDebugApp->setRefForShapeIOManager(m_serialShapeIOManager); + depthDebugApp = new DepthDebugApp(m_serialShapeIOManager); applications["depthDebug"] = depthDebugApp; kinectHandWavy = new KinectHandWavy(m_serialShapeIOManager,kinectManager); @@ -72,35 +67,41 @@ void AppManager::setup(){ void AppManager::setupShapeDisplayManagement() { // initialize communication with the shape display // This is where the particulars of the shape display are set (i.e. TRANSFORM, inFORM, or any other physical layout). - m_serialShapeIOManager = new TransformIOManager(kinectManager); + string shapeDisplayToUse = "inFORM"; + + if (shapeDisplayToUse == "TRANSFORM") { + m_serialShapeIOManager = new TransformIOManager(kinectManager); + } else if (shapeDisplayToUse == "inFORM") { + m_serialShapeIOManager = new InFormIOManager(kinectManager); + } else { + throw "unknown shape display type: " + shapeDisplayToUse; + } printf("Setting up Shape Display Management\n"); + // Size the pin arrays correctly based on the hardware specific dimension, and initialize them with zero values + heightsForShapeDisplay = std::vector>(m_serialShapeIOManager->shapeDisplaySizeX, std::vector(m_serialShapeIOManager->shapeDisplaySizeY)); + heightsFromShapeDisplay = std::vector>(m_serialShapeIOManager->shapeDisplaySizeX, std::vector(m_serialShapeIOManager->shapeDisplaySizeY)); // initialize shape display pin configs PinConfigs pinConfigs; pinConfigs.timeOfUpdate = elapsedTimeInSeconds(); - pinConfigs.gainP = DEFAULT_GAIN_P; - pinConfigs.gainI = DEFAULT_GAIN_I; - pinConfigs.maxI = DEFAULT_MAX_I; - pinConfigs.deadZone = DEFAULT_DEAD_ZONE; - pinConfigs.maxSpeed = DEFAULT_MAX_SPEED; + pinConfigs.gainP = m_serialShapeIOManager->getGainP(); + pinConfigs.gainI = m_serialShapeIOManager->getGainI(); + pinConfigs.maxI = m_serialShapeIOManager->getMaxI(); + pinConfigs.deadZone = m_serialShapeIOManager->getDeadZone(); + pinConfigs.maxSpeed = m_serialShapeIOManager->getMaxSpeed(); m_serialShapeIOManager->setGlobalPinConfigs(pinConfigs); timeOfLastPinConfigsUpdate = elapsedTimeInSeconds(); - // clear height and pin config buffers - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { - heightsForShapeDisplay[x][y] = 0; - heightsFromShapeDisplay[x][y] = 0; - pinConfigsForShapeDisplay[x][y] = pinConfigs; - } - } + + // Set the dimensions of the pinConfigs + pinConfigsForShapeDisplay.resize(m_serialShapeIOManager->shapeDisplaySizeX, std::vector(m_serialShapeIOManager->shapeDisplaySizeY, pinConfigs)); // allocate height pixels objects and clear contents - heightPixelsForShapeDisplay.allocate(SHAPE_DISPLAY_SIZE_X, SHAPE_DISPLAY_SIZE_Y, 1); + heightPixelsForShapeDisplay.allocate(m_serialShapeIOManager->shapeDisplaySizeX, m_serialShapeIOManager->shapeDisplaySizeY, 1); heightPixelsForShapeDisplay.set(0); - heightPixelsFromShapeDisplay.allocate(SHAPE_DISPLAY_SIZE_X, SHAPE_DISPLAY_SIZE_Y, 1); + heightPixelsFromShapeDisplay.allocate(m_serialShapeIOManager->shapeDisplaySizeX, m_serialShapeIOManager->shapeDisplaySizeY, 1); heightPixelsFromShapeDisplay.set(0); // allocate shape display graphics container and clear contents @@ -126,8 +127,8 @@ void AppManager::update(){ // note: manually looping over all pixels is important! the underlying // ofPixels char array is stored as unsigned char[y][x], while the // shape display heights are stored as unsigned char[x][y] - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int x = 0; x < m_serialShapeIOManager->shapeDisplaySizeX; x++) { + for (int y = 0; y < m_serialShapeIOManager->shapeDisplaySizeY; y++) { int xy = heightPixelsFromShapeDisplay.getPixelIndex(x, y); heightPixelsFromShapeDisplay[xy] = heightsFromShapeDisplay[x][y]; } @@ -143,8 +144,8 @@ void AppManager::update(){ // note: manually looping over all pixels is important! the underlying // ofPixels char array is stored as unsigned char[y][x], while the // shape display heights are stored as unsigned char[x][y] - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int x = 0; x < m_serialShapeIOManager->shapeDisplaySizeX; x++) { + for (int y = 0; y < m_serialShapeIOManager->shapeDisplaySizeY; y++) { int xy = heightPixelsForShapeDisplay.getPixelIndex(x, y); heightsForShapeDisplay[x][y] = heightPixelsForShapeDisplay[xy]; } diff --git a/src/AppManager.hpp b/src/AppManager.hpp index 459aea8..6e1cfb0 100644 --- a/src/AppManager.hpp +++ b/src/AppManager.hpp @@ -104,12 +104,12 @@ class AppManager : public ofBaseApp { // I/O data buffers // maybe rename to serialHeightOutput() - unsigned char heightsForShapeDisplay[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; + std::vector> heightsForShapeDisplay; // maybe rename to serialHeightInput() - unsigned char heightsFromShapeDisplay[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; + std::vector> heightsFromShapeDisplay; ofPixels heightPixelsForShapeDisplay; ofPixels heightPixelsFromShapeDisplay; - PinConfigs pinConfigsForShapeDisplay[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; + std::vector> pinConfigsForShapeDisplay; ofFbo graphicsForShapeDisplay; ofPixels colorPixels; ofPixels depthPixels; diff --git a/src/Applications/Application.cpp b/src/Applications/Application.cpp index 07b29ad..222590e 100644 --- a/src/Applications/Application.cpp +++ b/src/Applications/Application.cpp @@ -8,17 +8,17 @@ #include "Application.hpp" Application::Application() { - heightsForShapeDisplay.allocate(SHAPE_DISPLAY_SIZE_X, SHAPE_DISPLAY_SIZE_Y, OF_IMAGE_GRAYSCALE); - heightsForShapeDisplay.set(0); - heightsDrawingBuffer.allocate(SHAPE_DISPLAY_SIZE_X, SHAPE_DISPLAY_SIZE_Y); + // Default constructor }; Application::Application(SerialShapeIOManager *theCustomShapeDisplayManager){ - heightsForShapeDisplay.allocate(SHAPE_DISPLAY_SIZE_X, SHAPE_DISPLAY_SIZE_Y, OF_IMAGE_GRAYSCALE); - heightsForShapeDisplay.set(0); - heightsDrawingBuffer.allocate(SHAPE_DISPLAY_SIZE_X, SHAPE_DISPLAY_SIZE_Y); m_CustomShapeDisplayManager = theCustomShapeDisplayManager; + + heightsForShapeDisplay.allocate(theCustomShapeDisplayManager->shapeDisplaySizeX, theCustomShapeDisplayManager->shapeDisplaySizeY, OF_IMAGE_GRAYSCALE); + heightsForShapeDisplay.set(0); + heightsDrawingBuffer.allocate(theCustomShapeDisplayManager->shapeDisplaySizeX, theCustomShapeDisplayManager->shapeDisplaySizeY); + } void Application::setRefForShapeIOManager(SerialShapeIOManager* customIOManager){ @@ -30,9 +30,8 @@ void Application::getHeightsForShapeDisplay(ofPixels &heights) { heights = heightsForShapeDisplay; }; -void Application::getPinConfigsForShapeDisplay(PinConfigs configs[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) { - PinConfigs *src = (PinConfigs *) pinConfigsForShapeDisplay; - copy(src, src + SHAPE_DISPLAY_SIZE_2D, (PinConfigs *) configs); +void Application::getPinConfigsForShapeDisplay(std::vector>& configs) { + pinConfigsForShapeDisplay = configs; }; void Application::setHeightsFromShapeDisplayRef(const ofPixels *heights) { diff --git a/src/Applications/Application.hpp b/src/Applications/Application.hpp index ac58b91..09c2477 100644 --- a/src/Applications/Application.hpp +++ b/src/Applications/Application.hpp @@ -15,6 +15,7 @@ #include "PinConfigs.h" #include "../ShapeDisplayManagers/ShapeIOManager.hpp" #include "../ShapeDisplayManagers/TransformIOManager.hpp" +#include "../ShapeDisplayManagers/InFormIOManager.hpp" class Application { public: @@ -23,7 +24,7 @@ class Application { Application(SerialShapeIOManager *theCustomShapeDisplayManager); void getHeightsForShapeDisplay(ofPixels &heights); - void getPinConfigsForShapeDisplay(PinConfigs configs[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]); + void getPinConfigsForShapeDisplay(std::vector>& configs); void setHeightsFromShapeDisplayRef(const ofPixels *heights); void setPixelsFromKinectRefs(const ofPixels *colorPixels, const ofPixels *depthPixels); @@ -48,7 +49,7 @@ class Application { protected: ofPixels heightsForShapeDisplay; - PinConfigs pinConfigsForShapeDisplay[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; + std::vector> pinConfigsForShapeDisplay; const ofPixels *heightsFromShapeDisplay; bool hasHeightsFromShapeDisplay = false; diff --git a/src/Applications/DebuggingApps/AxisCheckerApp.cpp b/src/Applications/DebuggingApps/AxisCheckerApp.cpp index 9bf8ef1..73e4f8b 100644 --- a/src/Applications/DebuggingApps/AxisCheckerApp.cpp +++ b/src/Applications/DebuggingApps/AxisCheckerApp.cpp @@ -7,24 +7,27 @@ #include "AxisCheckerApp.hpp" +AxisCheckerApp::AxisCheckerApp(SerialShapeIOManager *theSerialShapeIOManager) : Application(theSerialShapeIOManager) { + cout << "AxisCheckerApp constructor" << endl; +} void AxisCheckerApp::update(float dt) { normalizedPhase += dt * 0.5; tally++; - tally %= SHAPE_DISPLAY_SIZE_X + SHAPE_DISPLAY_SIZE_Y; + tally %= m_CustomShapeDisplayManager->shapeDisplaySizeX + m_CustomShapeDisplayManager->shapeDisplaySizeY; updateHeights(); } void AxisCheckerApp::updateHeights() { if (checkerboard) { - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { int height; - if (x < SHAPE_DISPLAY_SIZE_X / 2 && y < SHAPE_DISPLAY_SIZE_Y / 2) { + if (x < m_CustomShapeDisplayManager->shapeDisplaySizeX / 2 && y < m_CustomShapeDisplayManager->shapeDisplaySizeY / 2) { height = 40; - } else if (x < SHAPE_DISPLAY_SIZE_X / 2) { + } else if (x < m_CustomShapeDisplayManager->shapeDisplaySizeX / 2) { height = 250; - } else if (y < SHAPE_DISPLAY_SIZE_Y / 2) { + } else if (y < m_CustomShapeDisplayManager->shapeDisplaySizeY / 2) { height = 110; } else { height = 180; @@ -34,13 +37,13 @@ void AxisCheckerApp::updateHeights() { } } } else { - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { int height; - if (tally < SHAPE_DISPLAY_SIZE_X) { + if (tally < m_CustomShapeDisplayManager->shapeDisplaySizeX) { height = x == tally ? 255 : 0; } else { - height = SHAPE_DISPLAY_SIZE_X + y == tally ? 255 : 0; + height = m_CustomShapeDisplayManager->shapeDisplaySizeX + y == tally ? 255 : 0; } int xy = heightsForShapeDisplay.getPixelIndex(x, y); heightsForShapeDisplay[xy] = height; diff --git a/src/Applications/DebuggingApps/AxisCheckerApp.hpp b/src/Applications/DebuggingApps/AxisCheckerApp.hpp index a05863b..c768149 100644 --- a/src/Applications/DebuggingApps/AxisCheckerApp.hpp +++ b/src/Applications/DebuggingApps/AxisCheckerApp.hpp @@ -15,6 +15,7 @@ class AxisCheckerApp : public Application { public: + AxisCheckerApp(SerialShapeIOManager *theCustomShapeDisplayManager); void update(float dt); void drawGraphicsForShapeDisplay(int x, int y, int width, int height); string appInstructionsText(); diff --git a/src/Applications/DebuggingApps/DepthDebugApp.cpp b/src/Applications/DebuggingApps/DepthDebugApp.cpp index 196ecb3..e2d0cba 100644 --- a/src/Applications/DebuggingApps/DepthDebugApp.cpp +++ b/src/Applications/DebuggingApps/DepthDebugApp.cpp @@ -7,6 +7,9 @@ #include "DepthDebugApp.hpp" +DepthDebugApp::DepthDebugApp(SerialShapeIOManager *theCustomShapeDisplayManager) : Application(theCustomShapeDisplayManager) { + cout << "DepthDebugApp constructor" << endl; +} void DepthDebugApp::update(float dt) { cout << "hello there debug depth"; diff --git a/src/Applications/DebuggingApps/DepthDebugApp.hpp b/src/Applications/DebuggingApps/DepthDebugApp.hpp index e013a51..eb3fa38 100644 --- a/src/Applications/DebuggingApps/DepthDebugApp.hpp +++ b/src/Applications/DebuggingApps/DepthDebugApp.hpp @@ -15,6 +15,8 @@ class DepthDebugApp : public Application { public: + DepthDebugApp(SerialShapeIOManager *theCustomShapeDisplayManager); + void update(float dt); void drawGraphicsForShapeDisplay(int x, int y, int width, int height); string appInstructionsText(); diff --git a/src/Applications/DebuggingApps/KinectDebugApp.cpp b/src/Applications/DebuggingApps/KinectDebugApp.cpp index 3314f71..92eb8fb 100644 --- a/src/Applications/DebuggingApps/KinectDebugApp.cpp +++ b/src/Applications/DebuggingApps/KinectDebugApp.cpp @@ -21,15 +21,22 @@ KinectDebugApp::KinectDebugApp(KinectManager* kinectManager){ } +KinectDebugApp::KinectDebugApp(SerialShapeIOManager *theCustomShapeDisplayManager, KinectManager *theKinectManager) : Application( theCustomShapeDisplayManager ) { + m_kinectManager = theKinectManager; + + setupDepthFloorMap(); + +} + void KinectDebugApp::setup() { setupDepthFloorMap(); } void KinectDebugApp::setupDepthFloorMap() { //set all pins to 0 - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { // This takes the 2 dimensional coordinates and turns them into a one dimensional index for the flattened array. int flattenedIndex = heightsForShapeDisplay.getPixelIndex(x, y); @@ -235,9 +242,9 @@ void KinectDebugApp::updateHeights() { float tempSum = 0; - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { // This takes the 2 dimensional coordinates and turns them into a one dimensional index for the flattened array. int flattenedIndex = heightsForShapeDisplay.getPixelIndex(x, y); diff --git a/src/Applications/DebuggingApps/KinectDebugApp.hpp b/src/Applications/DebuggingApps/KinectDebugApp.hpp index e1c0307..858f81b 100644 --- a/src/Applications/DebuggingApps/KinectDebugApp.hpp +++ b/src/Applications/DebuggingApps/KinectDebugApp.hpp @@ -20,6 +20,7 @@ class KinectDebugApp : public Application{ public: KinectDebugApp(KinectManager* kinectManager); + KinectDebugApp(SerialShapeIOManager *theCustomShapeDisplayManager, KinectManager *theKinectManager); void setup(); void update(float dt); diff --git a/src/Applications/KinectHandWavy.cpp b/src/Applications/KinectHandWavy.cpp index ba2d3cd..7329067 100644 --- a/src/Applications/KinectHandWavy.cpp +++ b/src/Applications/KinectHandWavy.cpp @@ -57,9 +57,11 @@ void KinectHandWavy::drawGraphicsForShapeDisplay(int x, int y, int width, int he //*** Contours are disabled, but maybe they will be useful in the future. //m_kinectManager->drawContours(); - - //*** Draw preview of the actuated pixel regions (sections). - drawPreviewActuatedSections(); + + if ( m_CustomShapeDisplayManager->getShapeDisplayName() == "TRANSFORM" ) { + //*** Draw preview of the actuated pixel regions (sections). + drawPreviewActuatedSections(); + } } // Draw a rectangle around the shape display pixels based on the mask info from settings.xml @@ -82,7 +84,7 @@ void KinectHandWavy::drawPreviewMaskRectangle() { ofFill(); } -// Draw a semi-transparent rectangle over each of the three the actuated sections. +// Draw a semi-transparent rectangle over each of the three the actuated sections. This should only be called when the shape display is a transFORM. void KinectHandWavy::drawPreviewActuatedSections() { // Get the width in inches of the the full transform surface (need to cast shape display manager object first). @@ -120,9 +122,9 @@ void KinectHandWavy::updateHeights() { ofPixels livePixels = m_CustomShapeDisplayManager->cropToActiveSurface( blurredDepthImg.getPixels() ); // Process the inputs and updates the 'heightsForShapeDisplay' property accordingly. - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { // This takes the 2 dimensional coordinates and turns them into a one dimensional index for the flattened array. int flattenedIndex = heightsForShapeDisplay.getPixelIndex(x, y); diff --git a/src/Applications/MqttTransmissionApp.cpp b/src/Applications/MqttTransmissionApp.cpp index 68023c0..2c1ef1f 100644 --- a/src/Applications/MqttTransmissionApp.cpp +++ b/src/Applications/MqttTransmissionApp.cpp @@ -13,15 +13,22 @@ #include #include +MqttTransmissionApp::MqttTransmissionApp(SerialShapeIOManager *theSerialShapeIOManager) : Application(theSerialShapeIOManager) { + cout << "MqttTransmissionApp constructor\n"; + m_CustomShapeDisplayManager = theSerialShapeIOManager; + + theNewHeights.resize( m_CustomShapeDisplayManager->shapeDisplaySizeX * m_CustomShapeDisplayManager->shapeDisplaySizeY ); + +} // zero matrix for reset std::string doob = "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; // Helper functions for array piece -int theHeights[SHAPE_DISPLAY_SIZE_X*SHAPE_DISPLAY_SIZE_Y]; +//int theHeights[SHAPE_DISPLAY_SIZE_X*SHAPE_DISPLAY_SIZE_Y]; std::string theStr; -string stringArray[SHAPE_DISPLAY_SIZE_X*SHAPE_DISPLAY_SIZE_Y]; +//string stringArray[SHAPE_DISPLAY_SIZE_X*SHAPE_DISPLAY_SIZE_Y]; string int_array_to_string(int int_array[], int size_of_array) { theStr = ""; @@ -39,13 +46,14 @@ std::vector string_to_int_array(std::string text){ return tokens; } - +/* void updateINTHEIGHTS(std::vector puma){ for (int i=0; i<1152; i++){ //printf("%s",puma.at(i).c_str()); theHeights[i] = stoi(puma.at(i)); } } + */ void MqttTransmissionApp::updateHeights() { //depression = touchDetector->significantDepressionAmidstStabilityPixels(); @@ -64,26 +72,37 @@ void MqttTransmissionApp::updateHeights() { if (string_to_int_array(doob).size() != 1152){ printf ("ERROR!"); printf("%i\n",string_to_int_array(doob).size()); - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { int xy = heightsForShapeDisplay.getPixelIndex(x, y); heightsForShapeDisplay[xy] = 30; } } }else{ - updateINTHEIGHTS(string_to_int_array(doob)); - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + //updateINTHEIGHTS(string_to_int_array(doob)); + std::vector puma = string_to_int_array(doob); + + int flatLength = m_CustomShapeDisplayManager->shapeDisplaySizeX * m_CustomShapeDisplayManager->shapeDisplaySizeY; + + for (int i=0; i< flatLength; i++){ + //printf("%s",puma.at(i).c_str()); + //theHeights[i] = stoi(puma.at(i)); + theNewHeights[i] = stoi(puma.at(i)); + } + + + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { int xy = heightsForShapeDisplay.getPixelIndex(x, y); // if (theHeights[xy] > 193){ // theHeights[xy] = 170; // } - heightsForShapeDisplay[xy] = theHeights[xy]+30;//heightScalar * height + heightOffset; + //heightsForShapeDisplay[xy] = theHeights[xy]+30;//heightScalar * height + heightOffset; - + heightsForShapeDisplay[xy] = theNewHeights[xy]+30; //if {//(heightsForShapeDisplay[xy] != theHeights[xy]){//(depression.getColor(x, y).r != 0) { //heightsForShapeDisplay[xy] = HEIGHT_MAX; diff --git a/src/Applications/MqttTransmissionApp.hpp b/src/Applications/MqttTransmissionApp.hpp index 566d30f..95b9fdf 100644 --- a/src/Applications/MqttTransmissionApp.hpp +++ b/src/Applications/MqttTransmissionApp.hpp @@ -14,6 +14,7 @@ class MqttTransmissionApp : public Application { public: + MqttTransmissionApp(SerialShapeIOManager *theCustomShapeDisplayManager); void update(float dt); void drawGraphicsForShapeDisplay(int x, int y, int width, int height); string appInstructionsText(); @@ -42,6 +43,8 @@ class MqttTransmissionApp : public Application { int are_we_setup = 0; + std::vector theNewHeights; + //some convenience params std::string m_doob = "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"; diff --git a/src/Applications/VideoPlayerApp.cpp b/src/Applications/VideoPlayerApp.cpp index b2fa431..d9a82d5 100755 --- a/src/Applications/VideoPlayerApp.cpp +++ b/src/Applications/VideoPlayerApp.cpp @@ -7,9 +7,20 @@ #include "VideoPlayerApp.hpp" +VideoPlayerApp::VideoPlayerApp(SerialShapeIOManager *theCustomShapeDisplayManager) : Application(theCustomShapeDisplayManager) { + cout << "VideoPlayerApp constructor\n"; +} + void VideoPlayerApp::setup() { //setupTransformedPixelMap(); - video.load("escher-5-slow.mov"); + + // Select a video appropriate for the shape display. + if (m_CustomShapeDisplayManager->getShapeDisplayName() == "TRANSFORM") { + video.load("escher-5-slow.mov"); + } else { + video.load("inFORM-escher-mode.mp4"); + } + video.play(); } @@ -29,9 +40,9 @@ void VideoPlayerApp::updateHeights() { // Pass the current video frame to the shape display manager to get the actuated pixels. ofPixels livePixels = m_CustomShapeDisplayManager->cropToActiveSurface(m_videoPixels); - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { + for (int x = 0; x < m_CustomShapeDisplayManager->shapeDisplaySizeX; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int y = 0; y < m_CustomShapeDisplayManager->shapeDisplaySizeY; y++) { // This takes the 2 dimensional coordinates and turns them into a one dimensional index for the flattened array. int flattenedIndex = heightsForShapeDisplay.getPixelIndex(x, y); @@ -47,7 +58,9 @@ void VideoPlayerApp::drawGraphicsForShapeDisplay(int x, int y, int width, int he video.draw(30, 300, 544, 128); // Draw the preview of the actuated pixels sections. - drawSectionPreviewFrameBuffer(30, 300, 544, 128); + if (m_CustomShapeDisplayManager->getShapeDisplayName() == "TRANSFORM") { + drawSectionPreviewFrameBuffer(30, 300, 544, 128); + } } void VideoPlayerApp::drawSectionPreviewFrameBuffer(int x, int y, int width, int height) { diff --git a/src/Applications/VideoPlayerApp.hpp b/src/Applications/VideoPlayerApp.hpp index c22287c..94871a6 100755 --- a/src/Applications/VideoPlayerApp.hpp +++ b/src/Applications/VideoPlayerApp.hpp @@ -13,6 +13,7 @@ class VideoPlayerApp : public Application { public: + VideoPlayerApp(SerialShapeIOManager *theCustomShapeDisplayManager); void setup(); void update(float dt); void drawGraphicsForShapeDisplay(int x, int y, int width, int height); diff --git a/src/Constants/constants.h b/src/Constants/constants.h index 1604271..892034e 100644 --- a/src/Constants/constants.h +++ b/src/Constants/constants.h @@ -36,58 +36,9 @@ using namespace std; // Transform specific constants -#define NUM_ARDUINOS 192 #define NUM_PINS_ARDUINO 6 -#define NUM_SERIAL_CONNECTIONS 6 -#define SERIAL_PORT_0 "/dev/tty.usbserial-A702YMNV" -#define SERIAL_PORT_1 "/dev/tty.usbserial-A702YLM2" -#define SERIAL_PORT_2 "/dev/tty.usbserial-A702YMNT" -#define SERIAL_PORT_3 "/dev/tty.usbserial-A702YLM6" -#define SERIAL_PORT_4 "/dev/tty.usbserial-A702YLM9" -#define SERIAL_PORT_5 "/dev/tty.usbserial-A30011Hp" - - - -const string SERIAL_PORTS[NUM_SERIAL_CONNECTIONS] = { - SERIAL_PORT_0, - SERIAL_PORT_1, - SERIAL_PORT_2, - SERIAL_PORT_3, - SERIAL_PORT_4, - SERIAL_PORT_5 -}; - -// Shape display table -// ------------------- -#define SHAPE_DISPLAY_SIZE_X 48 -#define SHAPE_DISPLAY_SIZE_Y 24 - #define SHAPE_DISPLAY_CAN_TALK_BACK 1 -#define HEIGHT_MIN 50 -#define HEIGHT_MAX 210 - -#define PINBLOCK_0_X_OFFSET 13 -#define PINBLOCK_0_WIDTH 16 - -#define PINBLOCK_1_X_OFFSET 43 -#define PINBLOCK_1_WIDTH 16 - -#define PINBLOCK_2_X_OFFSET 73 -#define PINBLOCK_2_WIDTH 16 - -// shape display derived dimensions, for convenience -#define SHAPE_DISPLAY_SIZE_2D (SHAPE_DISPLAY_SIZE_X * SHAPE_DISPLAY_SIZE_Y) -#define HEIGHT_RANGE (HEIGHT_MAX - HEIGHT_MIN) - -// TRANSFORM pin config defaults -#define DEFAULT_GAIN_P 1.5 -#define DEFAULT_GAIN_I 0.045 -#define DEFAULT_MAX_I 25 -#define DEFAULT_DEAD_ZONE 2 -#define DEFAULT_MAX_SPEED 200 - - #endif /* constants_h */ diff --git a/src/ShapeDisplayManagers/InFormIOManager.cpp b/src/ShapeDisplayManagers/InFormIOManager.cpp new file mode 100644 index 0000000..7c2a9cd --- /dev/null +++ b/src/ShapeDisplayManagers/InFormIOManager.cpp @@ -0,0 +1,140 @@ +// +// InFormIOManager.cpp +// neoForm +// +// Created by Jonathan Williams on 6/29/24. +// + +#include "InFormIOManager.hpp" + + +InFormIOManager::InFormIOManager() { + // Set the InForm specific hardware parameters here. + //shapeDisplayName = "InForm"; + + shapeDisplaySizeX = 24; + shapeDisplaySizeY = 24; + + numberOfArduinos = 96; + + // Size the pinBoards vector appropriately. + pinBoards.resize(numberOfArduinos); + + // Size the 2d heights array appropriately for the specific shape display hardware, and initialize it with zero values. + // This needs to happen in the subclass constructor because the superclass constructor fires first, and won't yet have the subclass specific constants. + heightsForShapeDisplay.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, 0)); + // Also size the array that receives height values from the shape display. + heightsFromShapeDisplay.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, 0)); + + pinHeightMin = 50; + pinHeightMax = 210; + pinHeightRange = pinHeightMax - pinHeightMin; + + // Pin config values, might be abstracted into a single array. + gainP = 1.5; + gainI = 0.045; + maxI = 25; + deadZone = 2; + maxSpeed = 200; + + // Make a new PinConfigs struct instance with the default values. + PinConfigs defaultPinConfigs; + defaultPinConfigs.timeOfUpdate = 0; + defaultPinConfigs.gainP = gainP; + defaultPinConfigs.gainI = gainI; + defaultPinConfigs.maxI = maxI; + defaultPinConfigs.deadZone = deadZone; + defaultPinConfigs.maxSpeed = maxSpeed; + + + + // Set the dimensions of the pinConfigs, and set all the elements to the defaultPinConfigs struct. + pinConfigsForShapeDisplay.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, defaultPinConfigs)); + + // Initialize pin tracking vectors. + pinDiscrepancy.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, 0)); + pinEnabled.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, true)); + pinStuckSinceTime.resize( shapeDisplaySizeX, std::vector(shapeDisplaySizeY, elapsedTimeInSeconds() )); + + + // Add serial connection strings to the vector of serial connections. + serialPorts.push_back("/dev/tty.usbserial-A30010PW"); + serialPorts.push_back("/dev/tty.usbserial-A702YLM3"); + serialPorts.push_back("/dev/tty.usbserial-A702YMNY"); + + // Connect to shape display. + connectToDisplay(); + + configureBoards(); +} + +// Secondary Constructor delegates to the primary constructor and adds the kinect reference. +InFormIOManager::InFormIOManager(KinectManager* kinectRef) : InFormIOManager() { + m_kinectManagerRef = kinectRef; +} + +void InFormIOManager::configureBoards() { + // set up coordinates for + for (int i = 0; i < numberOfArduinos; i++) { + // determine which serial connection each board is on: + // every 3rd and 4th board is on the second + if (i < 36) { //64 + pinBoards[i].serialConnection = 0; //((i / 2) % 2 == 0) ? 0 : 1 + } else if (i < 60) { //128 + pinBoards[i].serialConnection = 1; //((i / 2) % 2 == 0) ? 2 : 3 + } else { + pinBoards[i].serialConnection = 2; //((i / 2) % 2 == 0) ? 4 : 5 + } + // every 5th to 8th board is mounted upside down, so invert the height + if (i % 12 == 4 || i % 12 == 5 || i % 12 == 6 || i % 12 == 7) { + //printf(ā€œ%d\nā€, i % 12 == 8 || i % 12 == 9 || i % 12 == 10 || i % 12 == 11); + pinBoards[i].invertHeight = true; + } else{ + printf("%d\n", i % 12 == 8 || i % 12 == 9 || i % 12 == 10 || i % 12 == 11); + pinBoards[i].invertHeight = false; + } + //pinBoards[i].invertHeight = ((i / 4) % 2 == 0) ? false : true; + for (int j = 0; j < NUM_PINS_ARDUINO; j++) { + int currentRow = (int)(i / 4); + int currentColumn = 5 - j + (i % 4 * 6); + pinBoards[i].heights[j] = 0; + pinBoards[i].pinCoordinates[j][0] = currentRow; + pinBoards[i].pinCoordinates[j][1] = currentColumn; + } + // if ((i / 2) % 2 == 0) { // + // int pinCoordinateRows[NUM_PINS_ARDUINO]; + // + // //invert pin order if the boards are mounted rotated + // for (int count = 0; count < NUM_PINS_ARDUINO; count++) { + // pinCoordinateRows[NUM_PINS_ARDUINO - count - 1] = pinBoards[i].pinCoordinates[count][1]; + // } + // for (int count = 0; count < NUM_PINS_ARDUINO; count++) { + // pinBoards[i].pinCoordinates[count][1] = pinCoordinateRows[count]; + // } + // + // // also invert the pin height again if they are: + // pinBoards[i].invertHeight = !pinBoards[i].invertHeight; + // } + // last, orient the x-y coordinate axes to the desired external axes + for (int j = 0; j < NUM_PINS_ARDUINO; j++) { + unsigned char j0 = pinBoards[i].pinCoordinates[j][0]; + unsigned char j1 = pinBoards[i].pinCoordinates[j][1]; + pinBoards[i].pinCoordinates[j][0] = shapeDisplaySizeX - 1 - j0; + pinBoards[i].pinCoordinates[j][1] = shapeDisplaySizeY - 1 - j1; + } + } + + printBoardConfiguration(); + // flag configuration as complete + boardsAreConfigured = true; +} + +ofPixels InFormIOManager::cropToActiveSurface(ofPixels fullSurface) { + // Inform needs no cropping, but it does need to be resized to pin dimensions of the active surface. + // NOTE video mode doesn't need resizing, so check to see if the dimensions differ before resizing. + if (fullSurface.getWidth() != shapeDisplaySizeX || fullSurface.getHeight() != shapeDisplaySizeY) { + fullSurface.resize(shapeDisplaySizeX, shapeDisplaySizeY); + } + + return fullSurface; +} diff --git a/src/ShapeDisplayManagers/InFormIOManager.hpp b/src/ShapeDisplayManagers/InFormIOManager.hpp new file mode 100644 index 0000000..e1c98cf --- /dev/null +++ b/src/ShapeDisplayManagers/InFormIOManager.hpp @@ -0,0 +1,40 @@ +// +// InFormIOManager.hpp +// neoForm +// +// Created by Jonathan Williams on 6/29/24. +// + +#ifndef InFormIOManager_hpp +#define InFormIOManager_hpp + +#include +#include "ofMain.h" +#include "constants.h" +#include "SerialShapeIOManager.hpp" + +#include "PinConfigs.h" + +class InFormIOManager : public SerialShapeIOManager { +public: + InFormIOManager(); + + InFormIOManager(KinectManager* kinectRef); + + // Name to identify the shape display. + string getShapeDisplayName() { + // This is a method instead of a property only to simplify the inheritance by making the superclass declaration virtual. + return "inFORM"; + } + + // should pins that appear stuck be turned off at regular intervals? + bool enableStuckPinSafetyToggle = false; + + ofPixels cropToActiveSurface(ofPixels fullSurface); + +protected: + // setup hardware-specific board configuration + void configureBoards(); +}; + +#endif /* InFormIOManager_hpp */ diff --git a/src/ShapeDisplayManagers/SerialShapeIOManager.cpp b/src/ShapeDisplayManagers/SerialShapeIOManager.cpp index 59cf5f5..35b734c 100644 --- a/src/ShapeDisplayManagers/SerialShapeIOManager.cpp +++ b/src/ShapeDisplayManagers/SerialShapeIOManager.cpp @@ -25,22 +25,9 @@ SerialShapeIOManager::SerialShapeIOManager() { // stuck pin safety toggling can only be implemented if we have height data // from the shape display telling us whether pins are stuck enableStuckPinSafetyToggle = enableStuckPinSafetyToggle && heightsFromShapeDisplayAvailable; - - // initialize per-pin data arrays - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { - heightsForShapeDisplay[x][y] = 0; - heightsFromShapeDisplay[x][y] = 0; - pinDiscrepancy[x][y] = 0; - pinEnabled[x][y] = true; - pinStuckSinceTime[x][y] = timeOfLastConfigsRefresh; - } - } - - // connect to shape display - connectToDisplay(); } +// This constructor may not be necessary, it doesn't get called. SerialShapeIOManager::SerialShapeIOManager(KinectManager* kinectRef) { timeOfLastConfigsUpdate = elapsedTimeInSeconds(); timeOfLastConfigsRefresh = elapsedTimeInSeconds(); @@ -49,17 +36,6 @@ SerialShapeIOManager::SerialShapeIOManager(KinectManager* kinectRef) { // from the shape display telling us whether pins are stuck enableStuckPinSafetyToggle = enableStuckPinSafetyToggle && heightsFromShapeDisplayAvailable; - // initialize per-pin data arrays - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { - heightsForShapeDisplay[x][y] = 0; - heightsFromShapeDisplay[x][y] = 0; - pinDiscrepancy[x][y] = 0; - pinEnabled[x][y] = true; - pinStuckSinceTime[x][y] = timeOfLastConfigsRefresh; - } - } - // connect to shape display connectToDisplay(); @@ -67,10 +43,6 @@ SerialShapeIOManager::SerialShapeIOManager(KinectManager* kinectRef) { m_kinectManagerRef = kinectRef; } -// Destructor -SerialShapeIOManager::~SerialShapeIOManager() { - disconnectFromDisplay(); -} // Connect to the display void SerialShapeIOManager::connectToDisplay() { @@ -102,27 +74,24 @@ void SerialShapeIOManager::disconnectFromDisplay(bool clearHeights) { // close connections isConnected = false; - closeSerialConnections(); + + // No longer necessary, the unique_ptrs will automatically deallocate the objects when the vector is cleared or goes out of scope. + //closeSerialConnections(); } // Open serial connections to the display. Connections close automatically when // destroyed. void SerialShapeIOManager::openSerialConnections() { - for (int i = 0; i < NUM_SERIAL_CONNECTIONS; i++) { - serialConnections[i] = new SerialShapeIO(SERIAL_PORTS[i], SERIAL_BAUD_RATE, heightsFromShapeDisplayAvailable); - } -} - -// Close all serial connections to the display -void SerialShapeIOManager::closeSerialConnections() { - for (int i = 0; i < NUM_SERIAL_CONNECTIONS; i++) { - delete serialConnections[i]; + for (const auto& port : serialPorts) { + serialConnections.push_back(std::make_unique(port, SERIAL_BAUD_RATE, heightsFromShapeDisplayAvailable)); } + // No need for a closeSerialConnections function, as the unique_ptrs will automatically + // deallocate the objects when the vector is cleared or goes out of scope. } // Print board configuration settings to console for debugging void SerialShapeIOManager::printBoardConfiguration() { - for (int i = 0; i < NUM_ARDUINOS; i++) { + for (int i = 0; i < numberOfArduinos; i++) { printf("board: %d: ", i); for (int j = 0; j < NUM_PINS_ARDUINO; j++) { printf("%d,%d(%d); ", pinBoards[i].pinCoordinates[j][0], pinBoards[i].pinCoordinates[j][1], pinBoards[i].invertHeight); @@ -139,9 +108,8 @@ void SerialShapeIOManager::printBoardConfiguration() { //-------------------------------------------------------------- // Set the desired heights for the shape display -void SerialShapeIOManager::sendHeightsToShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) { - unsigned char *src = (unsigned char *) heights; - copy(src, src + SHAPE_DISPLAY_SIZE_2D, (unsigned char *) heightsForShapeDisplay); +void SerialShapeIOManager::sendHeightsToShapeDisplay( const std::vector>& heights ) { + heightsForShapeDisplay = heights; // update display update(); @@ -149,13 +117,12 @@ void SerialShapeIOManager::sendHeightsToShapeDisplay(unsigned char heights[SHAPE // Get the actual height values on the shape display. They will be copied into // the destination array passed in as the argument. -void SerialShapeIOManager::getHeightsFromShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) { +void SerialShapeIOManager::getHeightsFromShapeDisplay( const std::vector>& heights) { if (!heightsFromShapeDisplayAvailable) { - throw ("height data from shape display is not available on " + shapeDisplayName); + throw ("height data from shape display is not available on " + getShapeDisplayName()); } - unsigned char *src = (unsigned char *) heightsFromShapeDisplay; - copy(src, src + SHAPE_DISPLAY_SIZE_2D, (unsigned char *) heights); + heightsFromShapeDisplay = heights; } // Set a single height for the display. @@ -163,8 +130,8 @@ void SerialShapeIOManager::getHeightsFromShapeDisplay(unsigned char heights[SHAP // Note: shape display heights will be adjusted to fit within the clipping range // regardless of the value set. void SerialShapeIOManager::clearShapeDisplayHeights(int value) { - for (int i = 0; i < SHAPE_DISPLAY_SIZE_X; i++) { - for (int j = 0; j < SHAPE_DISPLAY_SIZE_Y; j++) { + for (int i = 0; i < shapeDisplaySizeX; i++) { + for (int j = 0; j < shapeDisplaySizeY; j++) { heightsForShapeDisplay[i][j] = value; } } @@ -178,18 +145,21 @@ void SerialShapeIOManager::clearShapeDisplayHeights(int value) { // //-------------------------------------------------------------- -void SerialShapeIOManager::setPinConfigs(PinConfigs configs[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) { - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { - pinConfigs[x][y] = configs[x][y]; +// This may be unecessary, it's no different from setGlobalPinConfigs and it never seems to be called. +void SerialShapeIOManager::setPinConfigs(std::vector>& configs) { + for (int x = 0; x < shapeDisplaySizeX; x++) { + for (int y = 0; y < shapeDisplaySizeY; y++) { + pinConfigsForShapeDisplay[x][y] = configs[x][y]; } } } +// Set all of the values of pinConfigsForShapeDisplay to the same value, passed as the configs parameter. +// I can't really say why this is necessary, but the boards don't get the right configs without it. void SerialShapeIOManager::setGlobalPinConfigs(PinConfigs configs) { - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { - pinConfigs[x][y] = configs; + for (int x = 0; x < shapeDisplaySizeX; x++) { + for (int y = 0; y < shapeDisplaySizeY; y++) { + pinConfigsForShapeDisplay[x][y] = configs; } } } @@ -208,8 +178,8 @@ void SerialShapeIOManager::toggleStuckPins() { double currentTime = elapsedTimeInSeconds(); - for (int x = 0; x < SHAPE_DISPLAY_SIZE_X; x++) { - for (int y = 0; y < SHAPE_DISPLAY_SIZE_Y; y++) { + for (int x = 0; x < shapeDisplaySizeX; x++) { + for (int y = 0; y < shapeDisplaySizeY; y++) { int expectedHeight = heightsForShapeDisplay[x][y]; int actualHeight = heightsFromShapeDisplay[x][y]; pinDiscrepancy[x][y] = abs(expectedHeight - actualHeight); @@ -236,17 +206,17 @@ void SerialShapeIOManager::toggleStuckPins() { // Clip all values to fit within the allowed range void SerialShapeIOManager::clipAllHeightValuesToBeWithinRange() { - float thresholdScalar = 1.0 * HEIGHT_RANGE / 255; - for (int i = 0; i < SHAPE_DISPLAY_SIZE_X; i++) { - for (int j = 0; j < SHAPE_DISPLAY_SIZE_Y; j++) { + float thresholdScalar = 1.0 * pinHeightRange / 255; + for (int i = 0; i < shapeDisplaySizeX; i++) { + for (int j = 0; j < shapeDisplaySizeY; j++) { // to rescale the values instead of clipping them, use this line: - //heightsForShapeDisplay[i][j] = heightsForShapeDisplay[i][j] * thresholdScalar + HEIGHT_MIN; + //heightsForShapeDisplay[i][j] = heightsForShapeDisplay[i][j] * thresholdScalar + pinHeightMin; - if (heightsForShapeDisplay[i][j] <= HEIGHT_MIN) { - heightsForShapeDisplay[i][j] = (unsigned char) HEIGHT_MIN; + if (heightsForShapeDisplay[i][j] <= pinHeightMin) { + heightsForShapeDisplay[i][j] = (unsigned char) pinHeightMin; } - else if (heightsForShapeDisplay[i][j] >= HEIGHT_MAX) { - heightsForShapeDisplay[i][j] = (unsigned char) HEIGHT_MAX; + else if (heightsForShapeDisplay[i][j] >= pinHeightMax) { + heightsForShapeDisplay[i][j] = (unsigned char) pinHeightMax; } } } @@ -255,7 +225,7 @@ void SerialShapeIOManager::clipAllHeightValuesToBeWithinRange() { // Copy data from storage in the 2D array to the corresponding arduino board // structures. Flip height values where needed to match the board's orientation. void SerialShapeIOManager::readyDataForArduinos() { - for (int i = 0; i < NUM_ARDUINOS; i++) { + for (int i = 0; i < numberOfArduinos; i++) { for (int j = 0; j < NUM_PINS_ARDUINO; j++) { int x = pinBoards[i].pinCoordinates[j][0]; int y = pinBoards[i].pinCoordinates[j][1]; @@ -264,8 +234,8 @@ void SerialShapeIOManager::readyDataForArduinos() { pinBoards[i].heights[j] = heightsForShapeDisplay[x][y]; // if they've been updated, copy the pin configs to the board - if (pinBoards[i].configs[j].timeOfUpdate < pinConfigs[x][y].timeOfUpdate) { - pinBoards[i].configs[j] = pinConfigs[x][y]; + if (pinBoards[i].configs[j].timeOfUpdate < pinConfigsForShapeDisplay[x][y].timeOfUpdate) { + pinBoards[i].configs[j] = pinConfigsForShapeDisplay[x][y]; pinBoards[i].timeOfLastConfigsUpdate = elapsedTimeInSeconds(); } @@ -304,12 +274,12 @@ void SerialShapeIOManager::update() { // send height data. if the display talks back, ask it what it's doing if (heightsFromShapeDisplayAvailable) { - for (int i = 0; i < NUM_ARDUINOS; i++) { + for (int i = 0; i < numberOfArduinos; i++) { sendHeightsToBoardAndRequestFeedback(i + 1, pinBoards[i].heights, pinBoards[i].serialConnection); } readHeightsFromBoards(); // gets actual heights from arduino boards } else { - for (int i = 0; i < NUM_ARDUINOS; i++) { + for (int i = 0; i < numberOfArduinos; i++) { sendHeightsToBoard(i + 1, pinBoards[i].heights, pinBoards[i].serialConnection); } } @@ -343,8 +313,9 @@ void SerialShapeIOManager::sendValueToAllBoards(unsigned char termId, unsigned c messageContents[i + 2] = (unsigned char) value; } - for (int i = 0; i < NUM_SERIAL_CONNECTIONS; i++) { - serialConnections[i]->writeMessage(messageContents); + // Iterate through all serial connections and send the message to each one. + for (auto& connection : serialConnections) { + connection->writeMessage(messageContents); } } @@ -417,7 +388,7 @@ void SerialShapeIOManager::sendConfigsToBoard(unsigned char boardId, PinConfigs // Send configuration values that have been updated to the display void SerialShapeIOManager::sendUpdatedConfigValues() { - for (int i = 0; i < NUM_ARDUINOS; i++) { + for (int i = 0; i < numberOfArduinos; i++) { if (timeOfLastConfigsUpdate < pinBoards[i].timeOfLastConfigsUpdate) { sendConfigsToBoard(i + 1, pinBoards[i].configs, pinBoards[i].serialConnection); } @@ -431,7 +402,7 @@ void SerialShapeIOManager::sendUpdatedConfigValues() { // that appear broken; invalid values can crop up over time from firmware issues // and connection noise. void SerialShapeIOManager::sendAllConfigValues() { - for (int i = 0; i < NUM_ARDUINOS; i++) { + for (int i = 0; i < numberOfArduinos; i++) { sendConfigsToBoard(i + 1, pinBoards[i].configs, pinBoards[i].serialConnection); } timeOfLastConfigsUpdate = elapsedTimeInSeconds(); @@ -441,13 +412,13 @@ void SerialShapeIOManager::sendAllConfigValues() { // Read actual heights from the boards void SerialShapeIOManager::readHeightsFromBoards() { // receive the current heights on the shape display - for (int i = 0; i < NUM_SERIAL_CONNECTIONS; i++) { + for (size_t i = 0; i < serialConnections.size(); i++) { while (serialConnections[i]->hasNewMessage()) { unsigned char messageContent[MSG_SIZE_RECEIVE]; serialConnections[i]->readMessage(messageContent); if (messageContent[0] == TERM_ID_HEIGHT_RECEIVE) { int boardAddress = messageContent[1] - 1; - if (boardAddress >= 0 && boardAddress <= NUM_ARDUINOS) { + if (boardAddress >= 0 && boardAddress <= numberOfArduinos) { for (int j = 0; j < 6; j++) { int height = messageContent[j + 2]; if (pinBoards[boardAddress].invertHeight) { diff --git a/src/ShapeDisplayManagers/SerialShapeIOManager.hpp b/src/ShapeDisplayManagers/SerialShapeIOManager.hpp index 328ceaf..d932323 100644 --- a/src/ShapeDisplayManagers/SerialShapeIOManager.hpp +++ b/src/ShapeDisplayManagers/SerialShapeIOManager.hpp @@ -29,27 +29,28 @@ class SerialPinBoard { int serialConnection; // what serial connection is it on? }; - -class SerialShapeIOManager : public ShapeIOManager { +class SerialShapeIOManager { public: SerialShapeIOManager(); SerialShapeIOManager(KinectManager* kinectRef); - ~SerialShapeIOManager(); + // Destructor + virtual ~SerialShapeIOManager(){ + disconnectFromDisplay(); + }; // send and receive height values - void sendHeightsToShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]); - void getHeightsFromShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]); + void sendHeightsToShapeDisplay(const std::vector>& heights); + void getHeightsFromShapeDisplay(const std::vector>& heights); void clearShapeDisplayHeights(int value=0); // setters for pin config values - void setPinConfigs(PinConfigs configs[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]); + void setPinConfigs(std::vector>& configs); void setGlobalPinConfigs(PinConfigs configs); // should pins that appear stuck be turned off at regular intervals? bool enableStuckPinSafetyToggle = false; - // the name of this shape display - string shapeDisplayName = "Serial Shape Display"; + virtual string getShapeDisplayName() { return "Shape Display Name"; } // Dan and Jonathan Custom API-like commands virtual ofPixels getKinectStream(){return feebsTEMP;} @@ -60,13 +61,28 @@ class SerialShapeIOManager : public ShapeIOManager { // Virtual class for hardware specific pin layouts. virtual std::vector createSections(float pixelsPerInch) {}; + // Public getters for protected hardware constants, these are specific to the pin configs so might be abstracted into a single array of values. + float getGainP() const { return gainP; } + float getGainI() const { return gainI; } + int getMaxI() const { return maxI; } + int getDeadZone() const { return deadZone; } + int getMaxSpeed() const { return maxSpeed; } + + // can heights be read from the display? + const bool heightsFromShapeDisplayAvailable = SHAPE_DISPLAY_CAN_TALK_BACK; + + // Shape display hardware constants, to be initialized by the relevant sub-class. + int shapeDisplaySizeX; + int shapeDisplaySizeY; + + int numberOfArduinos; + protected: // manage the connection to the shape display void connectToDisplay(); void disconnectFromDisplay(bool clearHeights=false); void openSerialConnections(); - void closeSerialConnections(); // setup hardware-specific board configuration virtual void configureBoards() = 0; @@ -93,15 +109,16 @@ class SerialShapeIOManager : public ShapeIOManager { void readHeightsFromBoards(); // serial communications objects - SerialShapeIO *serialConnections[NUM_SERIAL_CONNECTIONS]; - SerialPinBoard pinBoards[NUM_ARDUINOS]; + std::vector> serialConnections; + + std::vector pinBoards; // shape display height values (both intended and actual values) - unsigned char heightsForShapeDisplay[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; - unsigned char heightsFromShapeDisplay[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; + std::vector> heightsForShapeDisplay; + std::vector> heightsFromShapeDisplay; // pin behavior configurations - PinConfigs pinConfigs[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; + std::vector> pinConfigsForShapeDisplay; // initialization flags bool boardsAreConfigured = false; @@ -112,9 +129,10 @@ class SerialShapeIOManager : public ShapeIOManager { double timeOfLastConfigsRefresh; // properties for detecting stuck pins to toggle - int pinDiscrepancy[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; - bool pinEnabled[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; - double pinStuckSinceTime[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]; + std::vector> pinDiscrepancy; + std::vector> pinEnabled; + std::vector> pinStuckSinceTime; + const int pinDiscrepancyToggleThreshold = 100; const float secondsUntilPinToggledOff = 1.0; const float secondsUntilPinToggledOn = 3.0; @@ -123,6 +141,24 @@ class SerialShapeIOManager : public ShapeIOManager { ofPixels feebsTEMP; KinectManager* m_kinectManagerRef; + + // Shape display hardware constants (previously defined using #define preprocessor statements. + // These values are designed to be overridden by their respective individual shape display sub-classes (Transform, Inform, Cooperform, ets.) + + int pinHeightMin; + int pinHeightMax; + int pinHeightRange; + + // Pin configs, maybe split out into a single array instead of separate values. + float gainP; + float gainI; + int maxI; + int deadZone; + int maxSpeed; + + // Serial connection id strings + std::vector serialPorts; + }; #endif /* SerialShapeIOManager_hpp */ diff --git a/src/ShapeDisplayManagers/ShapeIOManager.hpp b/src/ShapeDisplayManagers/ShapeIOManager.hpp index aa78314..6339320 100644 --- a/src/ShapeDisplayManagers/ShapeIOManager.hpp +++ b/src/ShapeDisplayManagers/ShapeIOManager.hpp @@ -13,18 +13,20 @@ #include "constants.h" #include "PinConfigs.h" +// This has been dereferenced from the SerialShapeIOManager.hpp file, so maybe think about removing someday. + class ShapeIOManager { public: // virtual destructor allows delegation to derived class destructors when used polymorphically virtual ~ShapeIOManager() {}; // send and receive height values - virtual void sendHeightsToShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) = 0; - virtual void getHeightsFromShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) = 0; + //virtual void sendHeightsToShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) = 0; + //virtual void getHeightsFromShapeDisplay(unsigned char heights[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) = 0; virtual void clearShapeDisplayHeights(int value=0) = 0; // setters for pin config values - virtual void setPinConfigs(PinConfigs configs[SHAPE_DISPLAY_SIZE_X][SHAPE_DISPLAY_SIZE_Y]) = 0; + virtual void setPinConfigs(std::vector>& configs) = 0; virtual void setGlobalPinConfigs(PinConfigs configs) = 0; //virtual ofPixels getPinPixelsOnly(ofPixels fullPixels); diff --git a/src/ShapeDisplayManagers/TransformIOManager.cpp b/src/ShapeDisplayManagers/TransformIOManager.cpp index 3051eed..ec8140e 100644 --- a/src/ShapeDisplayManagers/TransformIOManager.cpp +++ b/src/ShapeDisplayManagers/TransformIOManager.cpp @@ -10,18 +10,76 @@ // Create new transformIOManager instance, setting up transFORM-specific board // configuration TransformIOManager::TransformIOManager() { + // Set the Transform specific hardware parameters here. + + shapeDisplaySizeX = 48; + shapeDisplaySizeY = 24; + + numberOfArduinos = 192; + + // Size the pinBoards vector appropriately. + pinBoards.resize(numberOfArduinos); + + // Size the 2d heights array appropriately for the specific shape display hardware, and initialize it with zero values. + // This needs to happen in the subclass constructor because the superclass constructor fires first, and won't yet have the subclass specific constants. + heightsForShapeDisplay.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, 0)); + // Also size the array that receives height values from the shape display. + heightsFromShapeDisplay.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, 0)); + + pinHeightMin = 50; + pinHeightMax = 210; + pinHeightRange = pinHeightMax - pinHeightMin; + + // Pin config values, might be abstracted into a single array. + gainP = 1.5; + gainI = 0.045; + maxI = 25; + deadZone = 2; + maxSpeed = 200; + + // Make a new PinConfigs struct instance with the default values. + PinConfigs defaultPinConfigs; + defaultPinConfigs.timeOfUpdate = 0; + defaultPinConfigs.gainP = gainP; + defaultPinConfigs.gainI = gainI; + defaultPinConfigs.maxI = maxI; + defaultPinConfigs.deadZone = deadZone; + defaultPinConfigs.maxSpeed = maxSpeed; + + + + // Set the dimensions of the pinConfigs, and set all the elements to the defaultPinConfigs struct. + pinConfigsForShapeDisplay.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, defaultPinConfigs)); + + // Initialize pin tracking vectors. + pinDiscrepancy.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, 0)); + pinEnabled.resize(shapeDisplaySizeX, std::vector(shapeDisplaySizeY, true)); + pinStuckSinceTime.resize( shapeDisplaySizeX, std::vector(shapeDisplaySizeY, elapsedTimeInSeconds() )); + + // Add serial connection strings to the vector of serial connections. + serialPorts.push_back("/dev/tty.usbserial-A702YMNV"); + serialPorts.push_back("/dev/tty.usbserial-A702YLM2"); + serialPorts.push_back("/dev/tty.usbserial-A702YMNT"); + serialPorts.push_back("/dev/tty.usbserial-A702YLM6"); + serialPorts.push_back("/dev/tty.usbserial-A702YLM9"); + serialPorts.push_back("/dev/tty.usbserial-A30011Hp"); + + + // Connect to shape display. + connectToDisplay(); + configureBoards(); } -TransformIOManager::TransformIOManager(KinectManager* kinectRef) { - configureBoards(); +// Secondary Constructor delegates to the primary constructor and adds the kinect reference. +TransformIOManager::TransformIOManager(KinectManager* kinectRef) : TransformIOManager() { m_kinectManagerRef = kinectRef; } // setup transFORM-specific board configuration void TransformIOManager::configureBoards() { // set up coordinates for - for (int i = 0; i < NUM_ARDUINOS; i++) { + for (int i = 0; i < numberOfArduinos; i++) { // determine which serial connection each board is on: // every 3rd and 4th board is on the second if (i < 64) { @@ -62,8 +120,8 @@ void TransformIOManager::configureBoards() { for (int j = 0; j < NUM_PINS_ARDUINO; j++) { unsigned char j0 = pinBoards[i].pinCoordinates[j][0]; unsigned char j1 = pinBoards[i].pinCoordinates[j][1]; - pinBoards[i].pinCoordinates[j][0] = SHAPE_DISPLAY_SIZE_X - 1 - j0; - pinBoards[i].pinCoordinates[j][1] = SHAPE_DISPLAY_SIZE_Y - 1 - j1; + pinBoards[i].pinCoordinates[j][0] = shapeDisplaySizeX - 1 - j0; + pinBoards[i].pinCoordinates[j][1] = shapeDisplaySizeY - 1 - j1; } } @@ -97,7 +155,7 @@ ofPixels TransformIOManager::cropToActiveSurface( ofPixels fullSurface ) { ofPixels combinedActiveZones = combineActiveZones(fullSurface, sections); // Scale and rotate the combined active zones - combinedActiveZones.resize(48, 24); + combinedActiveZones.resize(shapeDisplaySizeX, shapeDisplaySizeY); combinedActiveZones.rotate90(2); // Return the cropped and transformed image diff --git a/src/ShapeDisplayManagers/TransformIOManager.hpp b/src/ShapeDisplayManagers/TransformIOManager.hpp index 7662eb6..609d611 100644 --- a/src/ShapeDisplayManagers/TransformIOManager.hpp +++ b/src/ShapeDisplayManagers/TransformIOManager.hpp @@ -13,19 +13,22 @@ #include "constants.h" #include "SerialShapeIOManager.hpp" +#include "PinConfigs.h" + class TransformIOManager : public SerialShapeIOManager { public: TransformIOManager(); TransformIOManager(KinectManager* kinectRef); - // should pins that appear stuck be turned off at regular intervals? - bool enableStuckPinSafetyToggle = false; - // the name of this shape display - string shapeDisplayName = "transFORM"; + string getShapeDisplayName() { + // This is a method instead of a property only to simplify the inheritance by making the superclass declaration virtual. + return "TRANSFORM"; + } - void sendHeightsToShapeDisplay(); + // should pins that appear stuck be turned off at regular intervals? + bool enableStuckPinSafetyToggle = false; ofPixels getKinectStream();