diff --git a/car/Bonnie2019/MasterConf.h b/car/Bonnie2019/MasterConf.h index 2e03c22d..7f5c5530 100644 --- a/car/Bonnie2019/MasterConf.h +++ b/car/Bonnie2019/MasterConf.h @@ -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 diff --git a/lib/carpi/src/carpi.h b/lib/carpi/src/carpi.h index 083df936..cd1f18b7 100644 --- a/lib/carpi/src/carpi.h +++ b/lib/carpi/src/carpi.h @@ -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 diff --git a/lib/carpi/src/components/hardware/HardwarePump.h b/lib/carpi/src/components/hardware/HardwarePump.h index c7d3d4d5..cdc3895b 100644 --- a/lib/carpi/src/components/hardware/HardwarePump.h +++ b/lib/carpi/src/components/hardware/HardwarePump.h @@ -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); @@ -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); } @@ -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() { diff --git a/lib/carpi/src/runable/programs/PMotorController.h b/lib/carpi/src/runable/programs/PMotorController.h index 1de0fa74..dbf2d699 100644 --- a/lib/carpi/src/runable/programs/PMotorController.h +++ b/lib/carpi/src/runable/programs/PMotorController.h @@ -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 @@ -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; diff --git a/lib/carpi/src/runable/services/SCar.h b/lib/carpi/src/runable/services/SCar.h index c449b89d..537d47df 100644 --- a/lib/carpi/src/runable/services/SCar.h +++ b/lib/carpi/src/runable/services/SCar.h @@ -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); diff --git a/lib/carpi/src/runable/services/SSpeed.h b/lib/carpi/src/runable/services/SSpeed.h index e49090e4..cd02811b 100644 --- a/lib/carpi/src/runable/services/SSpeed.h +++ b/lib/carpi/src/runable/services/SSpeed.h @@ -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. @@ -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(); @@ -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 } }; diff --git a/platformio.ini b/platformio.ini index 88c71765..c044309a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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