Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
speedlimiter.cpp
- Committer:
- shovelcat
- Date:
- 2018-10-25
- Revision:
- 5:aef1fc6c0df1
- Parent:
- 4:a8c9f6a13633
- Child:
- 6:1a4ed88c9a4b
File content as of revision 5:aef1fc6c0df1:
/*
author: Sebastian Pelchat
date: october 2018
*/
#include "speedlimiter.hpp"
#define debug SpeedLimiter::pc->printf
Serial* SpeedLimiter::pc = new Serial(USBTX, USBRX);
SpeedLimiter::SpeedLimiter(const PinName& pedalInHi, const PinName& pedalInLo, const PinName& pedalOutHi, const PinName& pedalOutLo)
: _pedalInHi(pedalInHi)
, _pedalInLo(pedalInLo)
, _pedalOutHi(pedalOutHi)
, _pedalOutLo(pedalOutLo)
, _referenceSpeed(DISABLE_ECO_ALGO_TRIGGER)
, _measuredSpeed(0.0)
{
}
SpeedLimiter::~SpeedLimiter()
{
}
void SpeedLimiter::ipControllerTransferFunction()
{
// write voltages at beginning of function to prevent jitter
// voltage will be delayed by 1 call which is okay.
// pc->printf("H\n\r");
const float voutHi = getOutputPedalVoltageHi();
const float voutLo = getOutputPedalVoltageLo();
// pc->printf("Hi: %f\t Lo: %f\n\r", voutHi, voutLo);
writeAdcPedalHi(voutHi);
writeAdcPedalLo(voutLo);
// calculate voltage for next call
const float referenceSpeed = getReferenceSpeed();
float outputAdcVoltageHi = 0;
float outputAdcVoltageLo = 0;
if(referenceSpeed == DISABLE_ECO_ALGO_TRIGGER) {
outputAdcVoltageHi = ecoDisabledAlgorithm();
} else {
outputAdcVoltageHi = ecoEnabledAlgorithm();
}
// outputAdcVoltageHi = ADC_OUTPUT_MAX_VALUE / 2;
outputAdcVoltageLo = outputAdcVoltageHi / 2;
// pc->printf("tmpHi: %f\t tmpLo: %f\n\r", outputAdcVoltageHi, outputAdcVoltageLo);
setOutputPedalVoltageHi(outputAdcVoltageHi);
setOutputPedalVoltageLo(outputAdcVoltageLo);
}
// Returns voltage read on analog input port chosen for pedal input 1
float SpeedLimiter::readAdcPedalHi()
{
const float decPcValue = _pedalInHi.read();
const float voltage = decPcValue * ADC_INPUT_MAX_VALUE;
return voltage;
}
// Returns voltage read on analog input port chosen for pedal input 2
float SpeedLimiter::readAdcPedalLo()
{
const float decPcValue = _pedalInLo.read();
const float voltage = decPcValue * ADC_INPUT_MAX_VALUE;
return voltage;
}
// Accepts a value in volts, converts to % and sets ADC for pedal output 1
void SpeedLimiter::writeAdcPedalHi(const float voltage)
{
const float boundedValue = boundValue(voltage, PEDAL_HI_MIN_VALUE, PEDAL_HI_MAX_VALUE);
const float decValue = voltageToDecimal(boundedValue, ADC_OUTPUT_MAX_VALUE);
_pedalOutHi.write(decValue);
}
// Accepts a value in volts, converts to % and sets ADC for pedal output 2
void SpeedLimiter::writeAdcPedalLo(const float voltage)
{
const float boundedValue = boundValue(voltage, PEDAL_LO_MIN_VALUE, PEDAL_LO_MAX_VALUE);
const float decValue = voltageToDecimal(boundedValue, ADC_OUTPUT_MAX_VALUE);
_pedalOutLo.write(decValue);
}
float SpeedLimiter::ecoDisabledAlgorithm()
{
const float value = readAdcPedalHi();
return value;
}
float SpeedLimiter::ecoEnabledAlgorithm()
{
static bool first_acquisition = true;
// constantes calcules dans MATLAB
const double b0 = 3312.0;
const double b1 = -3061.0;
const double a1 = -1.0;
// valeurs anterieures
static double lastE = 0.0;
static double lastOut = 0.0;
// calculs
double Vm = getMeasuredSpeed();
double Vd = getReferenceSpeed();
double out = 0.0;
if (readAdcPedalHi() > 1) {
const double e = Vd - Vm;
// y(n) = b0 * x(n) + b1 * x(n-1) - a1 * y(n-1)
out = (b0 * e) + (b1 * lastE) - (a1 * lastOut);
lastE = e;
lastOut = out;
// out est maintenant en 'force'
out = (out / 133240.0 * (PEDAL_HI_MAX_VALUE-PEDAL_HI_MIN_VALUE)) + PEDAL_HI_MIN_VALUE;
if(first_acquisition) {
pc->printf("Acquisition start:\n\r");
first_acquisition = false;
}
// pc->printf("%f;", Vm);
// wait(5);
} else {
lastE = 0.00000000001;
lastOut = 0.00000000001;
first_acquisition = true;
}
pc->printf("Vm: %.2f\t Vd: %.2f\t Eh: %.2f\t El: %.2f\n\r", Vm, Vd, out, out/2);
return (float)out;
}
//float SpeedLimiter::ecoEnabledAlgorithm()
//{
// // valeurs anterieures
// static double x1 = 0.0;
// static double y1 = 0.0;
//
// // constantes calcules avec matlab
// const double b0 = 10793.0;
// const double b1 = -8513.5;
// const double a1 = -1.0;
//
// const double TRANS_k_gear = 20.5; //Gearbox ratio
// const double TRANS_eff = 0.91; // Efficiency of the transmission
// const double TRANS_R_wheel = 0.3175; // Radius of the wheel [m]
// const double TRANS_k = TRANS_k_gear/TRANS_R_wheel; // Global ratio of the transmission [m]
//
// const double G_forceToTorque = (1/TRANS_k) * TRANS_eff;
//
// // calculs
// const float Vm = getMeasuredSpeed();
// const float Vd = getReferenceSpeed();
// double y0 = 0.0;
// if (readAdcPedalHi() > 1) {
// const double x0 = Vd - Vm;
// y0 = ( (-a1*y1) + (b0*x0) + (b1*x1) ) * G_forceToTorque;
//
// const double deltaT = 20.0;
// const double deltaE = PEDAL_HI_MAX_VALUE - PEDAL_HI_MIN_VALUE;
// const double ratioTtoE = deltaE / deltaT / 159.63 * deltaE;
// y0 = y0 * ratioTtoE + PEDAL_HI_MIN_VALUE;
//
// // update des valeurs anterieurs
// x1 = x0;
// y1 = y0;
// }
//
// pc->printf("Vm: %f\t Vd: %f\t Eh: %f\t El\n\r", Vm, Vd, y0, y0/2);
//
// return (float)y0;
//}
// Returns 'value' bounded between 'lowerBound' and 'upperBound'
float SpeedLimiter::boundValue(float value, const float lowerBound, const float upperBound)
{
if(value < lowerBound) {
value = lowerBound;
} else if(value > upperBound) {
value = upperBound;
}
return value;
}
// Returns "value/reference" as a percentage in decimal form (0.5 for 50%)
float SpeedLimiter::voltageToDecimal(const float voltage, const float reference)
{
return voltage/reference;
}