All mbed code for control over dive planes, pump motor, valve motor, BCUs, UART interface, etc.
Dependencies: mbed ESC mbed MODDMA
robotic_fish_6/PumpWithValve/PumpWithValve.cpp
- Committer:
- juansal12
- Date:
- 2020-01-14
- Revision:
- 0:c3a329a5b05d
File content as of revision 0:c3a329a5b05d:
#include <PumpWithValve/PumpWithValve.h> // The static instance PumpWithValve pumpWithValve; void flipFlowUpStatic() { pumpWithValve.flipFlowUp(); } void flipFlowDownStatic() { pumpWithValve.flipFlowDown(); } //============================================ // Initialization //============================================ // Constructor PumpWithValve::PumpWithValve() : // Initialize variables pumpPWM(pumpPwmPin), valvePWM(valvePwmPin), //valveEncoder(encoderPinA, encoderPinB, NC, count2rev), // use X2 encoding by default //valveCurrent(valveCurrentPin), hallSignal(hallInterruptPin), valveLED(LED4) { hallSignal.rise(&flipFlowUpStatic); hallSignal.fall(&flipFlowDownStatic); frequency = 0; thrust = 0; yaw = 0; valveSide = true; valveV1 = 0; valveV2 = 0; Vfreq = 0; VfreqAdjusted = 0; Vset = 0; dVFreq = 0; freqErr = 0; prevFreqErr = 0; timer.start(); } void PumpWithValve::start() { valvePWM.write(0.0); // apply nothing to start pumpPWM.write(0.0); periodSide1 = 0.0; periodSide2 = 0.0; timer.reset(); valveControl.attach(&pumpWithValve, &PumpWithValve::setVoid, 0.08); } void PumpWithValve::stop() { valveControl.detach(); valvePWM.write(0.0); pumpPWM.write(0.0); } void PumpWithValve::flipFlowUp() { // when the hall sensor sees a rising edge, we have rotated 180 degrees // --> want to adjust the applied voltage based on the side we are on valveSide = true; //change boolean state, keeps track of which half of the rotation we are on valveLED = 1; periodSide1 = timer.read_us(); timer.reset(); freqAct = 1/(periodSide1 + periodSide2); } void PumpWithValve::flipFlowDown() { valveSide = false; valveLED = 0; periodSide2 = timer.read_us(); timer.reset(); freqAct = 1/(periodSide1 + periodSide2); } //============================================ // Processing //============================================ void PumpWithValve::set(float freq_in, float yaw_in, float thrust_in){ thrust = thrust_in; yaw = yaw_in; frequency = freq_in; } void PumpWithValve::setVoid() { //Centrifugal Pump pumpPWM.write(thrust); // set speed of the valve motor through the frequency value if (periodSide1 == 0 || periodSide2 == 0) { Vfreq = frequency * 400000; //just setting directly the voltage, scaled up; need to tune this value this->calculateYawMethod1(); } else { // don't be fooled by initialization values // Failure mode - if it has been a full (desired) period since a hall sensor has been read if (timer.read_us() > 1.0 / frequency) { pumpWithValve.stop(); // may have to add a condition that allows for sudden input changes } else { freqErr = frequency - freqAct; dVFreq = KpFreq * freqErr + KdFreq * (freqErr - prevFreqErr); prevFreqErr = freqErr; //reset previous frequency error Vfreq += dVFreq; this->calculateYawMethod1(); } } } void PumpWithValve::calculateYawMethod1() { // split tail frequency voltage into voltage on either side of the valve // TODO figure out ideal relationship between yaw and offf between V1 and V2 // is it additive or multiplicative? start with super simple math valveV1 = (1.0 + valveOffsetGain * yaw) * Vfreq; valveV2 = (1.0 - valveOffsetGain * yaw) * Vfreq; // TODO need to decide whether to give up frequency or yaw when we are at input limits if (valveV1 > 1.0) {valveV1 = 1.0;} else if (valveV1 < 0.0) {valveV1 = 0.05;} if (valveV2 > 1.0) {valveV2 = 1.0;} else if (valveV2 < 0.0) {valveV2 = 0.05;} // write valve voltage based on which side the hall sensor says we are on if (valveSide) { Vset = valveV1; } else { Vset = valveV2; } valvePWM.write(Vset); } void PumpWithValve::calculateYawMethod2() { if (yaw < 0.0 && !valveSide) { Vset = (1.0 + valveOffsetGain*yaw)*Vfreq; // 0.7 can be adjusted to a power of 2 if needed if (Vset > 1.0) { VfreqAdjusted = 1.0; } } else if (yaw > 0.0 && valveSide) { Vset = (1.0 - valveOffsetGain*yaw)*Vfreq; // 0.7 can be adjusted to a power of 2 if needed if (Vset < 0.0) { VfreqAdjusted = 0.05; } // needs to keep turning } else { Vset = Vfreq; VfreqAdjusted = Vfreq; } valvePWM.write(VfreqAdjusted); } float PumpWithValve::getVset() { return Vset;} bool PumpWithValve::getVside() { return valveSide; }