rusefi/firmware/controllers/algo/dynoview.cpp

166 lines
3.9 KiB
C++

/*
* @file dynoview.cpp
*
* @date Nov 29, 2020
* @author Alexandru Miculescu, (c) 2012-2020
*/
#include "pch.h"
#if EFI_DYNO_VIEW
#include "dynoview.h"
static DynoView dynoInstance;
void DynoView::update(vssSrc src) {
efitimeus_t timeNow, deltaTime = 0.0;
float speed,deltaSpeed = 0.0;
timeNow = getTimeNowUs();
speed = Sensor::getOrZero(SensorType::VehicleSpeed);
if (src == ICU) {
speed = efiRound(speed,1.0);
} else {
//use speed with 0.001 precision from source CAN
speed = efiRound(speed,0.001);
}
if(timeStamp != 0) {
if (vss != speed) {
deltaTime = timeNow - timeStamp;
if (vss > speed) {
deltaSpeed = (vss - speed);
direction = 1; //decceleration
} else {
deltaSpeed = speed - vss;
direction = 0; //acceleration
}
//save data
timeStamp = timeNow;
vss = speed;
}
//updating here would display acceleration = 0 at constant speed
updateAcceleration(deltaTime, deltaSpeed);
#if EFI_TUNER_STUDIO
if (engineConfiguration->debugMode == DBG_LOGIC_ANALYZER) {
engine->outputChannels.debugIntField1 = deltaTime;
engine->outputChannels.debugFloatField1 = vss;
engine->outputChannels.debugFloatField2 = speed;
engine->outputChannels.debugFloatField3 = deltaSpeed;
engine->outputChannels.debugFloatField4 = acceleration;
}
#endif /* EFI_TUNER_STUDIO */
updateHP();
} else {
//ensure we grab init values
timeStamp = timeNow;
vss = speed;
}
}
/**
* input units: deltaSpeed in km/h
* deltaTime in uS
*/
void DynoView::updateAcceleration(efitimeus_t deltaTime, float deltaSpeed) {
if (deltaSpeed != 0.0) {
acceleration = ((deltaSpeed / 3.6) / (deltaTime / US_PER_SECOND_F));
if (direction) {
//decceleration
acceleration *= -1;
}
} else {
acceleration = 0.0;
}
}
/**
* E = m*a
* ex. 900 (kg) * 1.5 (m/s^2) = 1350N
* P = F*V
* 1350N * 35(m/s) = 47250Watt (35 m/s is the final velocity)
* 47250 * (1HP/746W) = 63HP
* https://www.youtube.com/watch?v=FnN2asvFmIs
* we do not take resistence into account right now.
*/
void DynoView::updateHP() {
//these are actually at the wheel
//we would need final drive to calcualte the correct torque at the wheel
if (acceleration != 0) {
engineForce = engineConfiguration->vehicleWeight * acceleration;
enginePower = engineForce * (vss / 3.6);
engineHP = enginePower / 746;
if (Sensor::getOrZero(SensorType::Rpm) > 0) {
engineTorque = ((engineHP * 5252) / Sensor::getOrZero(SensorType::Rpm));
}
} else {
//we should calculate static power
}
}
#if EFI_UNIT_TEST
void DynoView::setAcceleration(float a) {
acceleration = a;
}
#endif
float DynoView::getAcceleration() {
return acceleration;
}
int DynoView::getEngineForce() {
return engineForce;
}
int DynoView::getEnginePower() {
return (enginePower/1000);
}
int DynoView::getEngineHP() {
return engineHP;
}
int DynoView::getEngineTorque() {
return (engineTorque/0.73756);
}
float getDynoviewAcceleration() {
return dynoInstance.getAcceleration();
}
int getDynoviewPower() {
return dynoInstance.getEnginePower();
}
/**
* Periodic update function called from SlowCallback.
* Only updates if we have Vss from input pin.
*/
void updateDynoView() {
if (isBrainPinValid(engineConfiguration->vehicleSpeedSensorInputPin) &&
(!engineConfiguration->enableCanVss)) {
dynoInstance.update(ICU);
}
}
/**
* This function is called after every CAN msg received, we process it
* as soon as we can to be more acurate.
*/
void updateDynoViewCan() {
if (!engineConfiguration->enableCanVss) {
return;
}
dynoInstance.update(CAN);
}
#endif /* EFI_DYNO_VIEW */