Created
August 7, 2020 14:10
-
-
Save kubark42/db7ef0ffecb3789610cf513cd1484f4a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// rcb api instantiation. | |
var GUI_log = ''; | |
var DATA_control = function(){ | |
} | |
var RPM_filter_arr = []; | |
var RPM_time_arr = []; | |
var RPM_filter_okCount = 0; | |
var previousValid = false; | |
// Filter the rpm frequency and convert to RPM | |
DATA_control.prototype.processElectricalRPM = function(RPM_HZ){ | |
//If data is valid, pass through LPF | |
if(RPM_HZ != 0){ | |
//Convert to RPM | |
var RPMval = 2*60*RPM_HZ/CONFIG.numberOfMotorPoles.value; | |
if(previousValid == false){ | |
//Force lpf to take the latest value | |
LPFmotorRPM.forceValue(RPMval); | |
previousValid = true; | |
}else{ | |
//Apply the lpf | |
LPFmotorRPM.update(RPMval); | |
} | |
}else{ | |
LPFmotorRPM.forceValue(0); | |
previousValid = false; | |
} | |
} | |
DATA_control.prototype.processOpticalRPM = function(RPM_HZ, Bside){ | |
//If data is valid, pass through LPF | |
if (RPM_HZ != 0 && !isNaN(RPM_Hz)){ | |
var RPMval; | |
if(Bside){ | |
RPMval = 60*RPM_HZ/CONFIG.numberOfOpticalTapeB.value; | |
LPFmotorOpticalRPMB.update(RPMval); | |
}else{ | |
RPMval = 60*RPM_HZ/CONFIG.numberOfOpticalTape.value; | |
LPFmotorOpticalRPM.update(RPMval); | |
} | |
} | |
else{ | |
if(Bside){ | |
LPFmotorOpticalRPMB.forceValue(0); | |
}else{ | |
LPFmotorOpticalRPM.forceValue(0); | |
} | |
} | |
} | |
// Tare the right and left load cell | |
DATA_control.prototype.tareLoadCells = function(callback){ | |
var doneTare = function(){ | |
console.log("Tare Cells complete."); | |
chrome.storage.local.set({'TARE_OFFSET': TARE_OFFSET}); | |
if (callback) callback(); | |
} | |
if(CONFIG.boardVersion === "Series 1580" || CONFIG.boardVersion === "Series 1520"){ | |
LPFLeft.forceNextValue(); | |
LPFRight.forceNextValue(); | |
LPFThrust.forceNextValue(); | |
// Wait for LPF to stabilize | |
setTimeout(function(){ | |
// Set tare value | |
TARE_OFFSET.loadCellLeftResetValue = -DATA.getLoadCellLeft(); | |
TARE_OFFSET.loadCellRightResetValue = -DATA.getLoadCellRight(); | |
TARE_OFFSET.loadCellThrustResetValue = -DATA.getLoadCellThrust(); | |
doneTare(); | |
}, TARE_OFFSET.tareTime); | |
} | |
if(CONFIG.boardVersion === "Series 1780"){ | |
for(var i=0;i<6;i++){ | |
LPFforcesA[i].forceNextValue(); | |
LPFforcesB[i].forceNextValue(); | |
} | |
// Wait for LPF to stabilize | |
setTimeout(function(){ | |
// Set tare value | |
if(TARE_OFFSET.sixAxisForcesNA === undefined){ | |
TARE_OFFSET.sixAxisForcesNA = [0,0,0,0,0,0]; | |
} | |
if(TARE_OFFSET.sixAxisForcesNB === undefined){ | |
TARE_OFFSET.sixAxisForcesNB = [0,0,0,0,0,0]; | |
} | |
for (var i=0;i<6;i++){ | |
TARE_OFFSET.sixAxisForcesNA[i] = -DATA.getSixAxisRaw(i, false); | |
TARE_OFFSET.sixAxisForcesNB[i] = -DATA.getSixAxisRaw(i, true); | |
} | |
doneTare(); | |
}, TARE_OFFSET.tareTime); | |
} | |
} | |
//Raw load cell data as given by the board (already calibrated technically) | |
DATA_control.prototype.getSixAxisRaw = function(channel, Bside){ | |
if(channel > 5 || channel < 0){ | |
console.log("Error, wrong channel requested"); | |
return 0; | |
} | |
if(Bside) | |
return LPFforcesB[channel].getValue(); | |
return LPFforcesA[channel].getValue(); | |
} | |
//Raw load cell data as given by the board (already calibrated technically) | |
DATA_control.prototype.getSixAxisTared = function(channel, Bside){ | |
if(channel > 5 || channel < 0){ | |
console.log("Error, wrong channel requested"); | |
return 0; | |
} | |
if(Bside){ | |
if(TARE_OFFSET.sixAxisForcesNB === undefined){ | |
return LPFforcesB[channel].getValue(); | |
} | |
return LPFforcesB[channel].getValue() + TARE_OFFSET.sixAxisForcesNB[channel]; | |
}else{ | |
if(TARE_OFFSET.sixAxisForcesNA === undefined){ | |
return LPFforcesA[channel].getValue(); | |
} | |
return LPFforcesA[channel].getValue() + TARE_OFFSET.sixAxisForcesNA[channel]; | |
} | |
} | |
//Raw load cell value in mV | |
DATA_control.prototype.getLoadCellRight = function(){ | |
return LPFRight.getValue()*1000; | |
} | |
//Raw load cell value in mV | |
DATA_control.prototype.getLoadCellLeft = function(){ | |
return LPFLeft.getValue()*1000; | |
} | |
//Raw load cell value in mV | |
DATA_control.prototype.getLoadCellThrust = function(){ | |
return LPFThrust.getValue()*1000; | |
} | |
//Returns the thrust in kg | |
DATA_control.prototype.getThrust = function(Bside){ | |
if(CONFIG.boardVersion === "Series 1580" || CONFIG.boardVersion === "Series 1520"){ | |
var calibratedThrust = (DATA.getLoadCellThrust() + TARE_OFFSET.loadCellThrustResetValue)*LOAD_CELLS_CALIBRATION.calibrationFactorThrust; | |
var thrust = calibratedThrust*LOAD_CELLS_CALIBRATION.thrustNominal/LOAD_CELLS_CALIBRATION.fullScaleVoltage; | |
if(CONFIG.reverseThrust.value){ | |
thrust = -thrust; | |
} | |
return thrust; | |
} | |
if(CONFIG.boardVersion === "Series 1780"){ | |
// FZ | |
var thrust = DATA.getSixAxisTared(4, Bside); | |
if((CONFIG.reverseThrust.value && !Bside)||(CONFIG.reverseThrustB.value && Bside)){ | |
thrust = -thrust; | |
} | |
return thrust; | |
} | |
return 0; | |
} | |
//Returns the thrust in kg | |
DATA_control.prototype.getDualThrust = function(){ | |
return DATA.getThrust(false)+DATA.getThrust(true); | |
} | |
//Returns the torque in Nm | |
DATA_control.prototype.getTorque = function(Bside){ | |
if(CONFIG.boardVersion === "Series 1580" || CONFIG.boardVersion === "Series 1520"){ | |
var calibratedLoadCellRight = (DATA.getLoadCellRight() + TARE_OFFSET.loadCellRightResetValue)*LOAD_CELLS_CALIBRATION.calibrationFactorRight; | |
var calibratedLoadCellLeft = (DATA.getLoadCellLeft() + TARE_OFFSET.loadCellLeftResetValue)*LOAD_CELLS_CALIBRATION.calibrationFactorLeft; | |
var difference = (LOAD_CELLS_CALIBRATION.calibrationFactorHingeRight*calibratedLoadCellRight - LOAD_CELLS_CALIBRATION.calibrationFactorHingeLeft*calibratedLoadCellLeft) * CONFIG.gravityConstant * LOAD_CELLS_CALIBRATION.leftRightNominal/LOAD_CELLS_CALIBRATION.fullScaleVoltage; //in Newtons | |
var torque = difference*LOAD_CELLS_CALIBRATION.hingeDistance/2; //Torque in Nm. Divided by two because two load cells. | |
if(CONFIG.reverseTorque.value){ | |
torque = -torque; | |
} | |
return torque; | |
} | |
if(CONFIG.boardVersion === "Series 1780"){ | |
// TZ | |
var torque = DATA.getSixAxisTared(5, Bside); | |
if((CONFIG.reverseTorque.value && !Bside)||(CONFIG.reverseTorqueB.value && Bside)){ | |
torque = -torque; | |
} | |
return torque; | |
} | |
return 0; | |
} | |
DATA_control.prototype.getDualTorque = function(){ | |
return DATA.getTorque(false) + DATA.getTorque(true); | |
} | |
//Returns measured weight in kg | |
DATA_control.prototype.getWeight = function(){ | |
var calibratedLoadCellRight = (DATA.getLoadCellRight() + TARE_OFFSET.loadCellRightResetValue)*LOAD_CELLS_CALIBRATION.calibrationFactorRight; | |
var calibratedLoadCellLeft = (DATA.getLoadCellLeft() + TARE_OFFSET.loadCellLeftResetValue)*LOAD_CELLS_CALIBRATION.calibrationFactorLeft; | |
var calibratedWeight = calibratedLoadCellRight + calibratedLoadCellLeft; | |
return calibratedWeight*LOAD_CELLS_CALIBRATION.leftRightNominal/LOAD_CELLS_CALIBRATION.fullScaleVoltage; | |
} | |
DATA_control.prototype.getESCVoltage = function(Bside){ | |
if(CONFIG.boardVersion === "Series 1580" || CONFIG.boardVersion === "Series 1520"){ | |
if(LPFescVoltage.getValue()<0){ | |
return 0.0; | |
} | |
return LPFescVoltage.getValue(); | |
} | |
if(CONFIG.boardVersion === "Series 1780"){ | |
if(Bside){ | |
if(LPFescVoltageB.getValue()<0){ | |
return 0.0; | |
} | |
return LPFescVoltageB.getValue(); | |
}else{ | |
if(LPFescVoltageA.getValue()<0){ | |
return 0.0; | |
} | |
return LPFescVoltageA.getValue(); | |
} | |
} | |
return 0; | |
} | |
DATA_control.prototype.getESCCurrent = function(Bside){ | |
if(CONFIG.boardVersion === "Series 1580" || CONFIG.boardVersion === "Series 1520"){ | |
var val = LPFescCurrent.getValue()+CONFIG.currentTare15xx.value; | |
//if(Math.abs(val) < 0.015) val = 0; | |
return val; | |
} | |
if(CONFIG.boardVersion === "Series 1780"){ | |
// Auto tare the current when voltage is zero (hall sensors have slight hysterisis) | |
/*if(LPFescVoltageA.getValue()<0.1){ | |
LPFescCurrentOffsetA.update(-LPFescCurrentA.getValue()); | |
return 0; | |
}*/ | |
if(Bside){ | |
return LPFescCurrentB.getValue()+CONFIG.currentTareB.value; | |
} | |
return LPFescCurrentA.getValue()+CONFIG.currentTareA.value; | |
} | |
return 0; | |
} | |
DATA_control.prototype.getESCCurrentBurst = function(Bside){ | |
var val; | |
if(CONFIG.boardVersion === "Series 1780"){ | |
if(Bside){ | |
val = LPFescCurrentBurstB.getValue()+CONFIG.currentTareB.value; | |
}else{ | |
val = LPFescCurrentBurstA.getValue()+CONFIG.currentTareA.value; | |
} | |
}else{ | |
val = LPFescCurrentBurst.getValue()+CONFIG.currentTare15xx.value; | |
} | |
if(Math.abs(val) < 0.01) | |
val = 0; | |
return val; | |
} | |
DATA_control.prototype.getElectricalRPM = function () { | |
var rpm = 0 | |
if (CONFIG.electricalRPMActive.value) { | |
rpm = LPFmotorRPM.getValue(); | |
} | |
return rpm; | |
} | |
DATA_control.prototype.getOpticalRPM = function (Bside) { | |
var rpm = 0; | |
if (CONFIG.opticalRPMActive.value) { | |
if(Bside){ | |
rpm = LPFmotorOpticalRPMB.getValue(); | |
}else{ | |
rpm = LPFmotorOpticalRPM.getValue(); | |
} | |
} | |
return rpm; | |
} | |
DATA_control.prototype.getRPM = function(Bside){ | |
var rpm; | |
switch (CONFIG.mainRPMsensor.value) { | |
case "optical": | |
rpm = DATA.getOpticalRPM(Bside); | |
break; | |
case "electrical": | |
rpm = DATA.getElectricalRPM(); | |
break; | |
default: | |
throw "Invalid RPM sensor type" | |
} | |
return rpm; | |
} | |
DATA_control.prototype.getTemperatures = function(){ | |
var result = []; | |
for (var i=0;i<CONFIG.tempProbesQty;i++){ | |
var id = SENSOR_DATA.temperature[i].id; | |
var name = getTempProbeLocation(id); | |
if(name === "") name = id; | |
var value = { | |
"value": SENSOR_DATA.temperature[i].value, | |
"id": id, | |
"label": name | |
} | |
result.push(value); | |
} | |
return result; | |
} | |
DATA_control.prototype.getAccelerometer = function(number){ | |
var acc = SENSOR_DATA.accelerometer[number]; | |
return acc; | |
} | |
DATA_control.prototype.getElectricalPower = function(Bside){ | |
//For the 1580, we used to get the power as another variable from the board, but now it reduces support to just calculate | |
//it live on the fly, because we get asked "why are the values slightly different". Also solves the problem of those who used a hack | |
//code to tare the current sensor (sometimes it looses it's zero) | |
var power = Math.abs(DATA.getESCCurrent(Bside) * DATA.getESCVoltage(Bside)); | |
if (math.abs(power)<0.01){ | |
power = 0; | |
} | |
return power; | |
} | |
DATA_control.prototype.getDualElectricalPower = function(){ | |
return DATA.getElectricalPower(true)+DATA.getElectricalPower(false); | |
} | |
DATA_control.prototype.getMechanicalPower = function(Bside){ | |
var mech_power = Math.abs(DATA.getTorque(Bside)*DATA.getRPM(Bside)*UNITS.conversions.rpm.rads); | |
return mech_power; | |
} | |
DATA_control.prototype.getMotorEfficiency = function(Bside){ | |
var efficiency; | |
if (DATA.getElectricalPower(Bside) == 0) { | |
efficiency = 0; | |
} | |
else { | |
efficiency = DATA.getMechanicalPower(Bside)/DATA.getElectricalPower(Bside)*100; | |
} | |
return efficiency; | |
} | |
DATA_control.prototype.getPropMechEfficiency = function (Bside) { | |
var efficiency; | |
if (DATA.getMechanicalPower(Bside) == 0) { | |
efficiency = 0; | |
} else { | |
efficiency = DATA.getThrust(Bside) / DATA.getMechanicalPower(Bside); | |
//Efficiency should not be over 100g/watts | |
if (efficiency > 0.1) { | |
efficiency = 0; | |
} | |
} | |
return Math.abs(efficiency); | |
} | |
DATA_control.prototype.getPropElecEfficiency = function (Bside) { | |
var efficiency; | |
if ((DATA.getElectricalPower(Bside) == 0) || (DATA.getRPM(Bside) == 0)) { | |
efficiency = 0; | |
} else { | |
efficiency = DATA.getThrust(Bside) / DATA.getElectricalPower(Bside); | |
//Efficiency should not be over 100g/watts | |
if (efficiency > 0.1) { | |
efficiency = 0; | |
} | |
} | |
return Math.abs(efficiency); | |
} | |
DATA_control.prototype.isPressureSensorAvailable = function () { | |
if (CONFIG.pSensorAvailable) { | |
return true; | |
} | |
else { | |
return false; | |
} | |
} | |
DATA_control.prototype.getPressureT = function () { | |
var temp; | |
// Output in degree C. See datasheet p.4 | |
temp = LPFpressureT.getValue() * (200) / 2047 -50; | |
return temp; | |
} | |
DATA_control.prototype.getPressureRaw = function () { | |
// Units are Pa | |
var pressure; | |
var Pmin = -1 * 6894.76; // Min pressure in Pa | |
var Pmax = 1 * 6894.76; // Min pressure in Pa | |
// Type A Sensor Datasheet p.4 | |
pressure = (LPFpressure.getValue() - 0.1 * 16383) * (Pmax - Pmin) / (0.8 * 16383) + Pmin; | |
// If the sensor is not connected | |
if (SENSOR_DATA.rawPressureP == 0) { | |
pressure = 0; | |
} | |
return pressure; | |
} | |
DATA_control.prototype.getPressure = function () { | |
// Units are Pa | |
var pressure; | |
pressure = CONFIG.pressureCal.value * (DATA.getPressureRaw() + CONFIG.pressureTare.value); | |
return pressure; | |
} | |
DATA_control.prototype.tarePressure = function tarePressure(callback){ | |
// The function will not execute is it is already doing something. | |
if (DATA.taringPressure === false || DATA.taringPressure == null) { | |
DATA.sampleInit = 50; | |
DATA.sample = DATA.sampleInit; | |
DATA.sum = 0; | |
DATA.taringPressure = true; | |
function averageSamples(callback) { | |
DATA.sum = DATA.sum + DATA.getPressureRaw(); | |
DATA.sample = DATA.sample - 1; | |
console.log(DATA.getPressureRaw()); | |
if (DATA.sample === 0) { | |
changeMemory(CONFIG.pressureTare, -DATA.sum / DATA.sampleInit); | |
DATA.taringPressure = false; | |
console.log("Tare Aispeed complete."); | |
if (callback) callback(); | |
return 0; | |
} | |
else { | |
setTimeout(function(){ | |
averageSamples(callback); | |
}, 100); | |
} | |
} | |
averageSamples(callback); | |
} | |
}; | |
//Tare the current | |
DATA_control.prototype.tareCurrent = function tareCurrent(callback){ | |
// The function will not execute is it is already doing something. | |
if (DATA.taringCurrent === false || DATA.taringCurrent == null) { | |
DATA.sampleInitCurr = 50; | |
DATA.sampleCurr = DATA.sampleInitCurr; | |
DATA.sumCurrA = 0; | |
DATA.sumCurrB = 0; | |
DATA.sumCurr15xx = 0; | |
DATA.taringCurrent = true; | |
function averageSamples(callback) { | |
DATA.sumCurrA += DATA.getESCCurrent() - CONFIG.currentTareA.value; | |
DATA.sumCurrB += DATA.getESCCurrent(true) - CONFIG.currentTareB.value; | |
DATA.sumCurr15xx += DATA.getESCCurrent() - CONFIG.currentTare15xx.value; | |
DATA.sampleCurr = DATA.sampleCurr - 1; | |
if (DATA.sampleCurr === 0) { | |
changeMemory(CONFIG.currentTareA, -DATA.sumCurrA / DATA.sampleInitCurr); | |
changeMemory(CONFIG.currentTareB, -DATA.sumCurrB / DATA.sampleInitCurr); | |
changeMemory(CONFIG.currentTare15xx, -DATA.sumCurr15xx / DATA.sampleInitCurr); | |
DATA.taringCurrent = false; | |
console.log("Tare Current complete."); | |
if (callback) callback(); | |
return 0; | |
} | |
else { | |
setTimeout(function(){ | |
averageSamples(callback); | |
}, 100); | |
} | |
} | |
averageSamples(callback); | |
} | |
}; | |
DATA_control.prototype.getAirSpeed = function () { | |
var airspeed; | |
// Ambiant pressure in Pa | |
var pAtm = CONFIG.atmPressure.value; | |
// In kelvin | |
var temperature = DATA.getPressureT() + 273.15; | |
// Air density; | |
var rho = pAtm / temperature / 287.058; | |
airspeed = Math.sqrt(Math.abs(2*(DATA.getPressure())/ rho)); | |
return airspeed; //airspeed; | |
} | |
DATA_control.prototype.getForwardFlightEfficiency = function () { | |
if (DATA.getElectricalPower() == 0) { | |
return 0; | |
} | |
else { | |
// Forward power / electrical power in percentage. | |
var out = Math.abs(DATA.getThrust() * 9.81 * DATA.getAirSpeed() / DATA.getElectricalPower() * 100); | |
return out; | |
} | |
} | |
var DATA = new DATA_control(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment