Skip to content

Commit

Permalink
New vetter Motor Current Calculation, add Pump Limitation
Browse files Browse the repository at this point in the history
  • Loading branch information
timoxd7 committed Mar 5, 2020
1 parent 2d539cf commit 09e82cd
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 36 deletions.
1 change: 1 addition & 0 deletions car/Bonnie2019/MasterConf.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//#define PMOTORCONTROLLER_DISABLE_MOTOR_POWER_OUTPUT
#define PMOTORCONTROLLER_ACTIVATE_RECUPERATION
//#define PMOTORCONTROLLER_USE_BRAKE_FOR_RECUPERATION
//#define DISABLE_PUMP
#include "carpi.h"

#define HIGH_DEMAND_SERVICE_REFRESH_RATE 120 // Hz
Expand Down
2 changes: 1 addition & 1 deletion lib/carpi/src/carpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
With this, all components, services and programs are included in the actual CarSoftware.
*/

#define CARPI_VERSION "V0.1.4-P1 - Add Recuperation & Add voltage reading for adaptive power limit"
#define CARPI_VERSION "V0.1.4-P2 - Add Recuperation & Add voltage reading for adaptive power limit"

// Prior include Platform-specific Components

Expand Down
22 changes: 18 additions & 4 deletions lib/carpi/src/components/hardware/HardwarePump.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@

#include "../interface/IPump.h"

#ifdef DISABLE_PUMP
#warning "Pump Disabled!"
#endif

#define PUMP_MAX_SPEED 0.6 // %

class HardwarePump : public IPump {
public:
HardwarePump(PinName pwmPort, PinName enablePort) : _pwmPort(pwmPort), _enablePort(enablePort) {
_enablePort = 0;
_pwmPort = 1;
_pwmPort = 1; // -> pump pwm off

setComponentType(COMPONENT_COOLING);
setObjectType(OBJECT_HARDWARE);
Expand All @@ -18,8 +24,14 @@ class HardwarePump : public IPump {
}

virtual void setSpeed(pump_speed_t speed) {
if (speed > 1) speed = 1;
if (speed < 0) speed = 0;
#ifdef DISABLE_PUMP
speed = 0;
#else
if (speed > 1) speed = 1;
if (speed < 0) speed = 0;

speed *= PUMP_MAX_SPEED;
#endif

_pwmPort.write(1 - speed);
}
Expand All @@ -29,7 +41,9 @@ class HardwarePump : public IPump {
}

virtual void setEnable(pump_enable_t enable) {
_enablePort.write(enable);
#ifndef DISABLE_PUMP
_enablePort.write(enable);
#endif
}

virtual pump_enable_t getEnable() {
Expand Down
10 changes: 5 additions & 5 deletions lib/carpi/src/runable/programs/PMotorController.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
#define STD_HARD_BRAKE_CUTOFF_APPS_POSITION 0.25 // 25% -> If equal or higher than that while hard brake, gas pedal will be unprimed

// HAS TO BE BOUNT TO SSPEED!!! The settings there define the max Current allowed, based on that, make the choice here
#define STD_MAX_RECUPERATION_PERCENTAGE 0.204 // % (245 A set Max at SSpeed -> ~50 A)
#define STD_MAX_RECUPERATION_PERCENTAGE 0.2 // % (250A set Max at SSpeed -> 50 A)
#define STD_RECU_SPEED_THRESHHOLD 2 // km/h - Under this speed, Recuperation is disabled
#define STD_RECU_SPEED_FULL 4 // km/h - From this speed up, recuperation is completely enabled

// Recuperation using the Brake Pedal. Only used, if "PMOTORCONTROLLER_USE_BRAKE_FOR_RECUPERATION" is defined
#ifdef PMOTORCONTROLLER_USE_BRAKE_FOR_RECUPERATION
#define STD_BRAKE_RECU_START 0.05 // % where the Brake-Pedal will activate recuperation
#define STD_BRAKE_RECU_MAX 0.20 // % where the Brake-Pedal reaches recuperation max
#define STD_BRAKE_RECU_START 0.15 // % where the Brake-Pedal will activate recuperation
#define STD_BRAKE_RECU_MAX 0.25 // % where the Brake-Pedal reaches recuperation max
#else
#define STD_GAS_RECU_THRESHHOLD 0.10 // % where the gas pedal will enter recuperation down below and power up above
#endif
Expand Down Expand Up @@ -68,12 +68,12 @@ class PMotorController : public IProgram {
#ifdef PMOTORCONTROLLER_ACTIVATE_RECUPERATION
#ifdef PMOTORCONTROLLER_USE_BRAKE_FOR_RECUPERATION
if (returnValue <= 0.00001) { // just to correct float error
float brakePosition = _pedal.brake->getValue();
float brakePosition = _brakePedal.object->getValue();
if (brakePosition > STD_BRAKE_RECU_START) {
if (brakePosition > STD_BRAKE_RECU_MAX) {
returnValue = -STD_MAX_RECUPERATION_PERCENTAGE;
} else {
returnValue = -STD_MAX_RECUPERATION_PERCENTAGE * _map(brakePedal, STD_BRAKE_RECU_START, STD_BRAKE_RECU_MAX, 0.0, 1.0);
returnValue = -STD_MAX_RECUPERATION_PERCENTAGE * _map(brakePosition, STD_BRAKE_RECU_START, STD_BRAKE_RECU_MAX, 0.0, 1.0);
}
} else {
returnValue = 0;
Expand Down
5 changes: 5 additions & 0 deletions lib/carpi/src/runable/services/SCar.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ class SCar : public IService {
}

void calibrationNeeded() {
if (_state = READY_TO_DRIVE) {
_motorController->setRUN(MOTOR_CONTROLLER_RUN_DISABLE);
_motorController->setRFE(MOTOR_CONTROLLER_RFE_DISABLE);
}

_state = CALIBRATION_NEEDED;
_resetLeds();
_led.yellow->setState(LED_ON);
Expand Down
87 changes: 69 additions & 18 deletions lib/carpi/src/runable/services/SSpeed.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,27 @@
#define STD_SPEED_DEVIANCE_THRESHHOLD 3 // kM/h -> if one sensor gives a higher Value than this, the other one will be compared
#define STD_MAX_SPEED_DEVIANCE 0.1 // 10%

#define STD_DISTANCE_PER_REVOLUTION 1.4451326206513048896928159563086 // m -> The distance a wheel will travel over one whole rotation
#define STD_DISTANCE_PER_REVOLUTION 1.43633616122 // m -> The distance a wheel will travel over one whole rotation
#define STD_MOTOR_TO_WHEEL_RATIO (1.0/3.6) // The gear Ratio from the Motor to the rear Wheels

// Values to Calculate the Power for the Adaptive Power Control
#define THROTTLE_ACTIVE // Comment do deactivate the Throttle according to the speed, dc voltage and the given values down below
#define ACCU_MIN_VOLTAGE 300 // V -> is only used, if the Voltage can't be red from the Inverter
#define ACCU_MAX_ALLOWED_POWER 80000 // W -> 80 kW
#define ACCU_MAX_ALLOWED_CURRENT 245 // A !!! Also change the value at PMotorController for the max allowed Recuperation % !!!
#define MOTOR_MAX_VOLTAGE 470 // V = Max Motor Voltage (according to datasheet)
#define MOTOR_MAX_VOLTAGE_SPEED_UNDER_LOAD 5170 // RPM
#define ACCU_MAX_ALLOWED_CURRENT 250 // A !!! Also change the value at PMotorController for the max allowed Recuperation % !!!
//#define MOTOR_MAX_VOLTAGE 470 // V = Max Motor Voltage (according to datasheet)
//#define MOTOR_MAX_VOLTAGE_SPEED_UNDER_LOAD 5170 // RPM
#define INVERTER_MAX_ALLOWED_CURRENT 424.3 // A (under field I max pk)

#define NEW_THROTTLE
#define INVERTER_MAX_ALLOWED_PHASE_CURRENT 300.0 // A
#define MOTOR_KN 0.0478 // Vrms/RPM

// Gets calculated at compilation
#define MOTOR_RPM_TO_KMH (STD_DISTANCE_PER_REVOLUTION * STD_MOTOR_TO_WHEEL_RATIO * 0.06) // =~ 0.02408554367752174816154693260514
#define MOTOR_VOLTAGE_TO_RPM_MULTIPLYER (MOTOR_MAX_VOLTAGE_SPEED_UNDER_LOAD / MOTOR_MAX_VOLTAGE)
#define ROOT_3 1.73205080757 // Needed for the chain factor
#define ROOT_2 1.41421356237 // Needed for AC to DC conversion

/*
Speed is measured by the front Wheels -> most accurat result.
Expand Down Expand Up @@ -181,6 +187,45 @@ class SSpeed : public IService {

void _setThrottle(speed_value_t speed) {
#ifdef THROTTLE_ACTIVE
#ifdef NEW_THROTTLE

float rpmSpeed = speed * (1/(float)MOTOR_RPM_TO_KMH);

float dcVoltage = _motorController->getDcVoltage();
// Only use this voltage if the Inverter already sent it
if (_motorController->getDcVoltageGotCount() < 1) {
dcVoltage = (float)ACCU_MIN_VOLTAGE;
}

float motorVoltage = rpmSpeed * (float)MOTOR_KN;
float maxAcVoltage = dcVoltage / (float)ROOT_2;
if (motorVoltage > maxAcVoltage) {
motorVoltage = maxAcVoltage;
}

float maxPossiblePower = motorVoltage * (float)INVERTER_MAX_ALLOWED_PHASE_CURRENT * (float)ROOT_3;

float powerLimit = 1.0;
if (maxPossiblePower > 0) {
// Now limit the power either by the allowed current OR by the allowed Power
float powerLimitByCurrent = (dcVoltage * (float)ACCU_MAX_ALLOWED_CURRENT) / maxPossiblePower;
float powerLimitByPower = (float)ACCU_MAX_ALLOWED_POWER / maxPossiblePower;

// Check the lower power setting
if (powerLimitByCurrent > powerLimitByPower)
powerLimit = powerLimitByPower;
else
powerLimit = powerLimitByCurrent;

// Limit to boundary
if (powerLimit > 1.0) powerLimit = 1.0;
else if (powerLimit < 0.0) powerLimit = 0.0;
}

// And shoot it down the channel
_carService.setMaxPower(powerLimit);

#else

// At first, get current DC Voltage
float dcVoltage = _motorController->getDcVoltage();
Expand All @@ -190,33 +235,39 @@ class SSpeed : public IService {
dcVoltage = ACCU_MIN_VOLTAGE;
}

// calculate the current Motor Voltage according to the Speed
// calculate the current Motor Voltage according to the Speed and limit it
float motorVoltage = ((speed / ((float)MOTOR_MAX_VOLTAGE_SPEED_UNDER_LOAD * (float)MOTOR_RPM_TO_KMH)) * MOTOR_MAX_VOLTAGE);
if (motorVoltage > MOTOR_MAX_VOLTAGE) motorVoltage = MOTOR_MAX_VOLTAGE;

// And limit it by the Accu Voltage
if (motorVoltage > (float)dcVoltage) motorVoltage = (float)dcVoltage;
if (motorVoltage > dcVoltage) motorVoltage = dcVoltage;

// Get the current max Power according to the Motor Voltage
float maxPossiblePower = motorVoltage * (float)INVERTER_MAX_ALLOWED_CURRENT;

// Now limit the power either by the allowed current OR by the allowed Power
float powerLimitByCurrent = (dcVoltage * (float)ACCU_MAX_ALLOWED_CURRENT) / maxPossiblePower;
float powerLimitByPower = (float)ACCU_MAX_ALLOWED_POWER / maxPossiblePower;

// Check the lower power setting
float powerLimit = 1.0;
if (powerLimitByCurrent >= powerLimitByPower)
powerLimit = powerLimitByPower;
else if (powerLimitByCurrent < powerLimitByPower)
powerLimit = powerLimitByCurrent;

// Limit to boundary
if (powerLimit > 1.0) powerLimit = 1.0;
if (powerLimit < 0.0) powerLimit = 0.0;
if (maxPossiblePower > 0) {
// Now limit the power either by the allowed current OR by the allowed Power
float powerLimitByCurrent = (dcVoltage * (float)ACCU_MAX_ALLOWED_CURRENT) / maxPossiblePower;
float powerLimitByPower = (float)ACCU_MAX_ALLOWED_POWER / maxPossiblePower;

// Check the lower power setting
if (powerLimitByCurrent >= powerLimitByPower)
powerLimit = powerLimitByPower;
else if (powerLimitByCurrent < powerLimitByPower)
powerLimit = powerLimitByCurrent;

// Limit to boundary
if (powerLimit > 1.0) powerLimit = 1.0;
if (powerLimit < 0.0) powerLimit = 0.0;
}

// And shoot it down the channel
_carService.setMaxPower(powerLimit);

#endif
#endif
}
};

Expand Down
16 changes: 8 additions & 8 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ env_default = Master
src_dir = car

[env:Dashboard]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_l432kc
framework = mbed
debug_tool = stlink
Expand All @@ -30,7 +30,7 @@ build_unflags =
-Os -std=gnu++98

[env:Pedal]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_l432kc
framework = mbed
debug_tool = stlink
Expand All @@ -47,7 +47,7 @@ build_unflags =
-Os -std=gnu++98

[env:Master]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_f767zi
framework = mbed
debug_tool = stlink
Expand All @@ -63,7 +63,7 @@ build_unflags =
-Os -std=gnu++98

[env:Master-Small]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_f446re
framework = mbed
debug_tool = stlink
Expand Down Expand Up @@ -97,7 +97,7 @@ build_unflags =
-Os -std=gnu++98

[env:Dashboard-Demo]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_f446re
framework = mbed
debug_tool = stlink
Expand All @@ -113,7 +113,7 @@ build_unflags =
-Os -std=gnu++98

[env:F446RE_TESTING]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_f446re
framework = mbed
debug_tool = stlink
Expand All @@ -127,7 +127,7 @@ build_unflags =
-Os -std=gnu++98

[env:F767ZI_TESTING]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_f767zi
framework = mbed
debug_tool = stlink
Expand All @@ -141,7 +141,7 @@ build_unflags =
-Os -std=gnu++98

[env:L432KC_TESTING]
platform = ststm32
platform = ststm32@5.6.0
board = nucleo_l432kc
framework = mbed
debug_tool = stlink
Expand Down

0 comments on commit 09e82cd

Please sign in to comment.