Skip to content

Instantly share code, notes, and snippets.

@kubark42
Created August 7, 2020 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubark42/db7ef0ffecb3789610cf513cd1484f4a to your computer and use it in GitHub Desktop.
Save kubark42/db7ef0ffecb3789610cf513cd1484f4a to your computer and use it in GitHub Desktop.
'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