commit 183689119ec95ac2a5e5842359a2efe6ca9b2e56 Author: Patrick McDonagh Date: Mon Jul 17 19:07:56 2017 -0500 First Commit diff --git a/AnalogInput.m b/AnalogInput.m new file mode 100644 index 0000000..6ff4dc7 --- /dev/null +++ b/AnalogInput.m @@ -0,0 +1,77 @@ +classdef AnalogInput < handle + properties + mux; + channel; + rawValue; + lastValue; + lastStored=0; + rawMax,rawMin,euMax,euMin; + history=zeros(1, 100, 'double'); + badReads=0; + + end + + properties(Access=private) + m,b; + end + + methods + function obj = AnalogInput(mux, channel, rawMin, rawMax, euMin, euMax) + obj.mux = mux; + obj.channel = channel; + obj.rawMin = double(rawMin); + obj.rawMax = double(rawMax); + obj.euMin = double(euMin); + obj.euMax = double(euMax); + + obj.m = (obj.euMax - obj.euMin) / (obj.rawMax - obj.rawMin); + obj.b = obj.euMax - obj.m * (obj.rawMax); + end + + function value = setValue(obj, inValue) + obj.rawValue = inValue; + value = obj.m * inValue + obj.b; + obj.lastValue = value; + obj.lastStored = now; + obj.history = [value, obj.history(1:end-1)]; + end + + function value = read(obj) + value = obj.lastValue; + rawIn = obj.mux.readAnalogSPI(); + if (rawIn ~= -1) + obj.badReads = 0; + value = obj.setValue(double(rawIn)); + else + obj.badReads = obj.badReads + 1; + end + + if (obj.badReads > 10) + pause(10); + end + end + + function value = readSim(obj, simRaw) + value = obj.m * simRaw + obj.b; + obj.lastValue = pv; + obj.lastValue = value; + obj.lastStored = now; + obj.history = [value, obj.history(1:end-1)]; + end + end + + methods(Static) + function test + pi = raspi('10.0.0.104', 'pi', 'raspberry'); + mux = MuxSetup(pi); + anInput1 = AnalogInput(mux, 1, 0.0, 65535.0, 0.0, 100.0); + anInput2 = AnalogInput(mux, 2, 0.0, 65535.0, 0.0, 100.0); + + anInput1.read() + anInput2.read() + end + + end + + +end diff --git a/Card.m b/Card.m new file mode 100644 index 0000000..8427142 --- /dev/null +++ b/Card.m @@ -0,0 +1,243 @@ +classdef Card < handle + properties + numPointsUsed = 0; + strokeNumber; + strokeStartTime; + + surfacePosition={}; + surfaceLoad={}; + downholePosition={}; + downholeLoad={}; + + surfacePositionMax=LPPair(0,0); + surfacePositionMin=LPPair(0,0); + surfaceLoadMax=LPPair(0,0); + surfaceLoadMin=LPPair(0,0); + + downholePositionMax=LPPair(0,0); + downholePositionMin=LPPair(0,0); + downholeLoadMax=LPPair(0,0); + downholeLoadMin=LPPair(0,0); + + topCorner=LPPair(0,0); + bottomCorner=LPPair(0,0); + + surfaceStrokeLength; + downholeNetStrokeLength; + downholeGrossStrokeLength; + downholeAdjustedGrossStrokeLength; + downholeLoadSpan; + fluidLoad; + pumpIntakePressure; + fluidLevel; + fillageEstimated; + fillageCalculated; + tubingMovement; + strokeSpeed; + + structuralLoading; + + polishedRodHorsepower; + pumpHorsepower; + fluidBblMoved; + fluidBblMovedAdjusted; + waterBblMoved; + oilBblMoved; + gasMcfMoved; + end + + methods + function obj=Card(strokeNumber) + % Initialization Function + obj.strokeNumber = strokeNumber; + obj.strokeStartTime = now; + end + + function push(obj, s_pos, s_load, d_pos, d_load) + obj.surfacePosition = [obj.surfacePosition s_pos]; + obj.surfaceLoad = [obj.surfaceLoad s_load]; + obj.downholePosition = [obj.downholePosition d_pos]; + obj.downholeLoad = [obj.downholeLoad d_load]; + end + + function calcStrokeData(obj, numSlices, fluidGradient, rodDepth, ... + anchorDepth, tubingCSA, pumpArea, frictionEstimate, ... + structuralRating, kFactor, waterBBLRatio, oilBBLRatio, ... + gasMCFRatio) + calculateSPM(); + obj.surfacePositionMax = obj.positionMax(obj.surfacePosition, obj.surfaceLoad, obj.numPointsUsed); + obj.surfaceLoadMax = obj.loadMax(obj.surfacePosition, obj.surfaceLoad, obj.numPointsUsed); + obj.surfacePositionMin = obj.positionMin(obj.surfacePosition, obj.surfaceLoad, obj.numPointsUsed); + obj.surfaceLoadMin = obj.loadMin(obj.surfacePosition, obj.surfaceLoad, obj.numPointsUsed); + + obj.downholePositionMax = obj.positionMax(obj.downholePosition, obj.downholeLoad, obj.numPointsUsed); + obj.downholeLoadMax = obj.loadMax(obj.downholePosition, obj.downholeLoad, obj.numPointsUsed); + obj.downholePositionMin = obj.positionMin(obj.downholePosition, obj.downholeLoad, obj.numPointsUsed); + obj.downholeLoadMin = obj.loadMin(obj.downholePosition, obj.downholeLoad, obj.numPointsUsed); + + obj.surfaceStrokeLength = obj.surfacePositionMax.position - obj.surfacePositionMin.position; + obj.downholeGrossStrokeLength = obj.downholePositionMax.position - obj.downholePositionMin.position; + obj.downholeLoadSpan = obj.downholeLoadMax.load - obj.downholeLoadMin.load; + + dxSurf = (obj.surfacePositionMax.position - obj.surfacePositionMin.position) / double(numSlices); + dxDown = (obj.downholePositionMax.position - obj.downholePositionMin.position) / double(numSlices); + + obj.pumpHorsepower = 0.0; + obj.polishedRodHorsepower = 0.0; + dhDistanceTop = 0.0; + dhDistanceBottom = 0.0; + + for i = 1:numSlices+1 + suPosTarget = obj.surfacePositionMin.position + (double(i) * dxSurf); + dhPosTarget = obj.downholePositionMin.position + (double(i) * dxDown); + suLoadAtTargetTop = 0.0; + suLoadAtTargetBottom = 0.0; + dhLoadAtTargetTop = 0.0; + dhLoadAtTargetBottom = 0.0; + + for j = 1:obj.numPointsUsed + if (obj.downholePosition(j) <= dhPosTarget && obj.downholePosition(j+1) > dhPosTarget) + dhLoadAtTargetTop = lineResolve(obj.downholePosition(j), obj.downholePosition(j+1), obj.downholeLoad(j), obj.downholeLoad(j+1), dhPosTarget); + end + + if (obj.downholePosition(j) > dhPosTarget && obj.downholePosition(j+1) >= dhPosTarget) + dhLoadAtTargetBottom = lineResolve(obj.downholePosition(j), obj.downholePosition(j+1), obj.downholeLoad(j), obj.downholeLoad(j+1), dhPosTarget); + end + + if (obj.surfacePosition(j) <= suPosTarget && obj.surfacePosition(j+1) > suPosTarget) + suLoadAtTargetTop = lineResolve(obj.surfacePosition(j), obj.surfacePosition(j+1), obj.surfaceLoad(j), obj.surfaceLoad(j+1), suPosTarget); + end + + if (obj.surfacePosition(j) > suPosTarget && obj.surfacePosition(j+1) >= suPosTarget) + suLoadAtTargetBottom = lineResolve(obj.surfacePosition(j), obj.surfacePosition(j+1), obj.surfaceLoad(j), obj.surfaceLoad(j+1), suPosTarget); + end + end + + obj.polishedRodHorsepower = obj.polishedRodHorsepower + (dxSurf / 12.0) * (suLoadAtTargetTop - suLoadAtTargetBottom) * (obj.strokeSpeed / 33000.0); + obj.pumpHorsepower = obj.pumpHorsepower + (dxDown / 12.0) * (dhLoadAtTargetTop - dhLoadAtTargetBottom) * (obj.strokeSpeed / 33000.0); + + tDistance = obj.distanceToLine(dhPosTarget, dhLoadAtTargetTop); + bDistance = obj.distanceToLine(dhPosTarget, dhLoadAtTargetBottom); + + if (tDistance > dhDistanceTop) + dhDistanceTop = tDistance; + obj.topCorner = LPPair(dhPosTarget, dhLoadAtTargetTop); + end + + if (bDistance > dhDistanceBottom) + dhDistanceBottom = bDistance; + obj.bottomCorner = LPPair(dhPosTarget, dhLoadAtTargetBottom); + end + end + + obj.downholeAdjustedGrossStrokeLength = obj.downholePositionMax.position - obj.topCorner.position; + obj.downholeNetStrokeLength = obj.bottomCorner.position - obj.downholePositionMin.position; + obj.fillageCalculated = (obj.downholeNetStrokeLength / obj.downholeAdjustedGrossStrokeLength) * 100.0; + obj.fillageEstimated =(obj.downholeNetStrokeLength / obj.downholeGrossStrokeLength) * 100.0; + obj.fluidBBLMoved = obj.downholeNetStrokeLength * pumpArea * 0.00010307; + obj.fluidBBLMovedAdjusted = obj.fluidBBLMoved * kFactor; + obj.oilBBLMoved = obj.fluidBBLMoved * oilBBLRatio; + obj.waterBBLMoved = obj.fluidBBLMoved * waterBBLRatio; + obj.gasMCFMoved = obj.fluidBBLMoved * gasMCFRatio; + + + if (obj.fillageEstimated > 100) + obj.fillageEstimated = 100.0; + end + + if (obj.fillageEstimated < 0.0) + obj.fillageEstimated = 0.0; + end + + if (obj.fillageCalculated > 100) + obj.fillageCalculated = 100.0; + end + + if (obj.fillageCalculated < 0.0) + obj.fillageCalculated = 0.0; + end + + obj.fluidLoad = obj.downholeLoadSpan - frictionEstimate; + obj.pumpIntakePressure = fluidGradient * rodDepth - (obj.fluidLoad / pumpArea); + obj.fluidLevel = obj.pumpIntakePressure / fluidGradient; + obj.tubingMovement = 12 * (rodDepth - anchorDepth) * obj.fluidLoad / (30500000 * tubingCSA); + obj.structuralLoading = (obj.surfaceLoadMax.load / (structuralRating * 100)) * 100; + end + + function calculateSPM(obj) + obj.strokeSpeed = 60000.0 / (now - obj.strokeStartTime); + end + + function dist = distanceToLine(pos, load) + % Finds the distance between a point and a line between the + % Max Position at Max Load and Min Position at Min Load + x1 = obj.downholePositionMin.position; + x2 = obj.downholePositionMax.position; + y1 = obj.downholeLoadMin.load; + y2 = obj.downholeLoadMax.load; + + dist = abs((y2-y1)* pos - (x2-x1)* load + x2*y1 - y2*x1) / sqrt(power(y2-y1, 2) + power(x2-x1,2)); + end + + function foundPoint = positionMax(positionArr, loadArr, arrSize) + maxPos = positionArr(1); + loadAtMaxP = -inf; + for i = 1:arrSize + maxPos = max(maxPos, positionArr(i)); + if (maxPos == positionArr(i)) + loadAtMaxP = loadArr(i); + end + end + foundPoint = LPPair(maxPos, loadAtMaxP); + end + + + function foundPoint = positionMin(positionArr, loadArr, arrSize) + minPosition = positionArr(1); + loadAtMinP = inf; + for i = 1:arrSize + minPosition = min(minPosition, positionArr(i)); + if (minPosition == positionArr(i)) + loadAtMinP = loadArr(i); + end + end + foundPoint = LPPair(minPosition, loadAtMinP); + end + + function foundPoint = loadMax(positionArr, loadArr, arrSize) + maxLoad = loadArr(1); + posAtMaxL = -inf; + for i = 1:arrSize + maxLoad = max(maxLoad, loadArr(i)); + if (maxLoad == positionArr(i)) + posAtMaxL = positionArr(i); + end + end + foundPoint = LPPair(posAtMaxL, maxLoad); + end + + function foundPoint = loadMin(positionArr, loadArr, arrSize) + minLoad = loadArr(1); + posAtMinL = inf; + for i = 1:arrSize + minLoad = min(minLoad, loadArr(i)); + if (minLoad == positionArr(i)) + posAtMinL = positionArr(i); + end + end + foundPoint = LPPair(posAtMinL, minLoad); + end + + end + + methods(Static) + function yTest = lineResolve(x1, x2, y1, y2, xTest) + % Uses the standard line equation to find the y value given x + line_m = (y2 - y1) / (x2 - x1); + line_b = y1 - line_m * x1; + yTest = line_m * xTest + line_b; + end + end + + +end diff --git a/Database.m b/Database.m new file mode 100644 index 0000000..6a2e280 --- /dev/null +++ b/Database.m @@ -0,0 +1,37 @@ + +classdef Database < handle + properties + hostname; + username; + password; + database='poc'; + port=27017; + mongo; + end + + methods + function obj = Database(hostname, username, password) + javaaddpath 'mongo-java-driver-3.4.2.jar'; + import com.mongodb.*; + obj.hostname = hostname; + obj.username = username; + obj.password = password; + credential = MongoCredential.createCredential(obj.username, obj.database, obj.password); + obj.mongo = MongoClient(obj.hostname, obj.port); +% obj.mongodbconn = mongodatabase(hostname, obj.port, obj.database, 'UserName', username, 'Password', password); %#ok<*NOPTS> + end + end + + methods(Static) + function test + db = Database('localhost', 'poc_java', 'HenryPump@1903'); + database = db.mongo.getDatabase(db.database); + database.auth(db.username, db.password); + cards = database.getCollection('cards'); + + cards.count() + end + end + + +end \ No newline at end of file diff --git a/DigitalInput.m b/DigitalInput.m new file mode 100644 index 0000000..429b326 --- /dev/null +++ b/DigitalInput.m @@ -0,0 +1,45 @@ +classdef DigitalInput < handle + properties + mux; + channel; + value; + end + + methods + function obj = DigitalInput(mux, channel) + obj.channel = channel; + obj.mux = mux; + end + + function val = read(obj) + obj.mux.set(obj.channel); + val = obj.mux.readDigital(); + end + end + + methods(Static) + function test + pi = raspi('10.0.0.104', 'pi', 'raspberry'); + mux = MuxSetup(pi); + digIn1 = DigitalInput(mux, 1); + digIn2 = DigitalInput(mux, 2); + digIn3 = DigitalInput(mux, 3); + digIn4 = DigitalInput(mux, 4); + digIn5 = DigitalInput(mux, 5); + digIn6 = DigitalInput(mux, 6); + digIn7 = DigitalInput(mux, 7); + digIn8 = DigitalInput(mux, 8); + + digIn1Val = digIn1.read() + digIn2Val = digIn2.read() + digIn3Val = digIn3.read() + digIn4Val = digIn4.read() + digIn5Val = digIn5.read() + digIn6Val = digIn6.read() + digIn7Val = digIn7.read() + digIn8Val = digIn8.read() + end + end + + +end \ No newline at end of file diff --git a/DigitalOutput.m b/DigitalOutput.m new file mode 100644 index 0000000..1412f25 --- /dev/null +++ b/DigitalOutput.m @@ -0,0 +1,76 @@ +classdef DigitalOutput < handle + properties + channel; + dev; + end + methods + function writeOut(obj, value) + writeDigitalPin(obj.dev, obj.channel, value); + end + + function obj = DigitalOutput(dev, chan) + channel = 0; + switch chan + case 1 + channel = 21; + case 2 + channel = 20; + case 3 + channel = 16; + case 4 + channel = 12; + case 5 + channel = 25; + case 6 + channel = 24; + case 7 + channel = 23; + case 8 + channel = 18; + end + configurePin(dev, channel, 'DigitalOutput'); + obj.dev = dev; + obj.channel = channel; + end + end + methods(Static) + function test + pi = raspi('10.0.0.104', 'pi', 'raspberry'); + + d1 = DigitalOutput(pi, 1); + d2 = DigitalOutput(pi, 2); + d3 = DigitalOutput(pi, 3); + d4 = DigitalOutput(pi, 4); + d5 = DigitalOutput(pi, 5); + d6 = DigitalOutput(pi, 6); + + d1.writeOut(1); + pause(0.250); + d2.writeOut(1); + pause(0.250); + d3.writeOut(1); + pause(0.250); + d4.writeOut(1); + pause(0.250); + d5.writeOut(1); + pause(0.250); + d6.writeOut(1); + pause(0.250); + + d1.writeOut(0); + pause(0.250); + d2.writeOut(0); + pause(0.250); + d3.writeOut(0); + pause(0.250); + d4.writeOut(0); + pause(0.250); + d5.writeOut(0); + pause(0.250); + d6.writeOut(0); + end + end +end + + + \ No newline at end of file diff --git a/LPPair.m b/LPPair.m new file mode 100644 index 0000000..dc5b8bf --- /dev/null +++ b/LPPair.m @@ -0,0 +1,17 @@ + +classdef LPPair < handle + % Load & Position Pair Class + properties + load; + position; + end + methods + function obj=LPPair(position, load) + obj.position = position; + obj.load = load; + end + end +end + + + diff --git a/LPStatus.m b/LPStatus.m new file mode 100644 index 0000000..ae769bd --- /dev/null +++ b/LPStatus.m @@ -0,0 +1,15 @@ +classdef LPStatus < handle + % Load, Position, & Status Class + properties + load; + position; + status; + end + methods + function obj=LPPair(position, load, status) + obj.position = position; + obj.load = load; + obj.status = status; + end + end +end \ No newline at end of file diff --git a/MuxSetup.m b/MuxSetup.m new file mode 100644 index 0000000..5241d6e --- /dev/null +++ b/MuxSetup.m @@ -0,0 +1,63 @@ +classdef MuxSetup < handle + properties(Access=private) + mux1Pin=5; + mux2Pin=6; + mux3Pin=13; + digInPin=19; + anOutTriggerPin=23; + dev; + end + + properties + setup=[0 0 0; 1 0 0; 0 1 0; 1 1 0; 0 0 1; 1 0 1; 0 1 1; 1 1 1]; + spiDevice; + end + + methods + function obj = MuxSetup(dev) + obj.dev = dev; + configurePin(dev, obj.mux1Pin, 'DigitalOutput'); + configurePin(dev, obj.mux2Pin, 'DigitalOutput'); + configurePin(dev, obj.mux3Pin, 'DigitalOutput'); + configurePin(dev, obj.digInPin, 'DigitalInput'); + configurePin(dev, obj.anOutTriggerPin, 'DigitalOutput'); + obj.spiDevice = spidev(dev, 'CE0'); + end + + function set(obj, channel) + % Set the mux up for reading from a channel + if (channel > 0) && (channel <= 8) + writeDigitalPin(obj.dev, obj.mux1Pin, obj.setup(channel, 1)); + writeDigitalPin(obj.dev, obj.mux2Pin, obj.setup(channel, 2)); + writeDigitalPin(obj.dev, obj.mux3Pin, obj.setup(channel, 3)); + end + + end + + function digInVal = readDigital(obj) + % Read the value of a digital input after setting the Mux + digInVal = ~readDigitalPin(obj.dev, obj.digInPin); + end + + function analogValue = readAnalogSPI(obj) + enableSPI(obj.dev); + analogValue = -1; + analogRaw = writeRead(obj.spiDevice,[hex2dec('00') hex2dec('00') hex2dec('00')]); + if (analogRaw(3) == 13) + x = uint16(analogRaw(1)) * 256; + analogValue = x + uint16(analogRaw(2)); + end +% disableSPI(obj.dev); + end + end + methods(Static) + function test + pi = raspi('10.0.0.104', 'pi', 'raspberry'); + mux = MuxSetup(pi); + mux.set(1); + mux.readAnalogSPI() + mux.set(2); + mux.readAnalogSPI() + end + end +end \ No newline at end of file diff --git a/mongo-java-driver-3.4.2.jar b/mongo-java-driver-3.4.2.jar new file mode 100644 index 0000000..1149adf Binary files /dev/null and b/mongo-java-driver-3.4.2.jar differ diff --git a/test.m b/test.m new file mode 100644 index 0000000..911aa0d --- /dev/null +++ b/test.m @@ -0,0 +1,6 @@ + +% DigitalOutput.test() +% MuxSetup.test() +% AnalogInput.test() +% DigitalInput.test() +Database.test() \ No newline at end of file