Improved speed simulation
This commit is contained in:
parent
fa6a4f5b09
commit
b811e128cd
@ -1,15 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
interface SimulationParameters {
|
interface SimulationParameters {
|
||||||
batteryCapacity: number,
|
batteryCapacity: number;
|
||||||
emptyVehicleWeight: number,
|
emptyVehicleWeight: number;
|
||||||
driverWeight: number,
|
driverWeight: number;
|
||||||
additionalWeight: number,
|
additionalWeight: number;
|
||||||
humanPower: number,
|
humanPower: number;
|
||||||
averageSpeed: number,
|
speedLimit: number;
|
||||||
climateZone: string,
|
climateZone: string;
|
||||||
dailyDistance: number,
|
dailyDistance: number;
|
||||||
dailyAscendingElevation: number
|
dailyAscendingElevation: number;
|
||||||
|
flatTerrainRatio: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
function runSimulation(parameters: SimulationParameters): Simulator.SimulationResult {
|
function runSimulation(parameters: SimulationParameters): Simulator.SimulationResult {
|
||||||
@ -21,9 +22,9 @@ function runSimulation(parameters: SimulationParameters): Simulator.SimulationRe
|
|||||||
vehicle.driverWeight= parameters.driverWeight;
|
vehicle.driverWeight= parameters.driverWeight;
|
||||||
vehicle.additionalWeight = parameters.additionalWeight;
|
vehicle.additionalWeight = parameters.additionalWeight;
|
||||||
vehicle.humanPower = parameters.humanPower;
|
vehicle.humanPower = parameters.humanPower;
|
||||||
vehicle.averageSpeed = parameters.averageSpeed;
|
vehicle.speedLimit = parameters.speedLimit;
|
||||||
let solarIrradiance: number[] = climateData[parameters.climateZone.toLowerCase()];
|
let solarIrradiance: number[] = climateData[parameters.climateZone.toLowerCase()];
|
||||||
let planning = new Simulator.OutingPlanning(parameters.dailyDistance, parameters.dailyAscendingElevation);
|
let planning = new Simulator.OutingPlanning(parameters.dailyDistance, parameters.dailyAscendingElevation, parameters.flatTerrainRatio);
|
||||||
|
|
||||||
let simulationResult = Simulator.simulate(vehicle, solarIrradiance, planning);
|
let simulationResult = Simulator.simulate(vehicle, solarIrradiance, planning);
|
||||||
//console.log(solarIrradiance);
|
//console.log(solarIrradiance);
|
||||||
@ -68,13 +69,15 @@ function initializeSimulator(container: HTMLElement) {
|
|||||||
driverWeight: Number((<HTMLInputElement>container.querySelector('[name=driver-weight]')).value),
|
driverWeight: Number((<HTMLInputElement>container.querySelector('[name=driver-weight]')).value),
|
||||||
additionalWeight: Number((<HTMLInputElement>container.querySelector('[name=additional-weight]')).value),
|
additionalWeight: Number((<HTMLInputElement>container.querySelector('[name=additional-weight]')).value),
|
||||||
humanPower: Number((<HTMLInputElement>container.querySelector('[name=human-power]')).value),
|
humanPower: Number((<HTMLInputElement>container.querySelector('[name=human-power]')).value),
|
||||||
averageSpeed: Number((<HTMLInputElement>container.querySelector('[name=average-speed]')).value),
|
speedLimit: Number((<HTMLInputElement>container.querySelector('[name=speed-limit]')).value),
|
||||||
climateZone: (<HTMLSelectElement>container.querySelector('.zone-selector')).value,
|
climateZone: (<HTMLSelectElement>container.querySelector('.zone-selector')).value,
|
||||||
dailyDistance: Number((<HTMLInputElement>container.querySelector('[name=daily-distance]')).value),
|
dailyDistance: Number((<HTMLInputElement>container.querySelector('[name=daily-distance]')).value),
|
||||||
dailyAscendingElevation: Number((<HTMLInputElement>container.querySelector('[name=daily-elevation]')).value),
|
dailyAscendingElevation: Number((<HTMLInputElement>container.querySelector('[name=daily-elevation]')).value),
|
||||||
|
flatTerrainRatio: Number((<HTMLInputElement>container.querySelector('[name=flat-ratio]')).value) / 100.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let simulationResult = runSimulation(parameters);
|
let simulationResult = runSimulation(parameters);
|
||||||
|
console.log(simulationResult);
|
||||||
|
|
||||||
let resultsContainer = container.querySelector('.simulation-results');
|
let resultsContainer = container.querySelector('.simulation-results');
|
||||||
|
|
||||||
@ -82,10 +85,17 @@ function initializeSimulator(container: HTMLElement) {
|
|||||||
let totalConsumedGridPower = simulationResult.cumulatedGridRechargeEnergy / simulationResult.vehicle.batteryEfficiency / simulationResult.vehicle.gridTransformerEfficiency;
|
let totalConsumedGridPower = simulationResult.cumulatedGridRechargeEnergy / simulationResult.vehicle.batteryEfficiency / simulationResult.vehicle.gridTransformerEfficiency;
|
||||||
|
|
||||||
let solarRechargeRatio = Math.round(100*(simulationResult.cumulatedSolarRechargeEnergy/(simulationResult.cumulatedSolarRechargeEnergy + simulationResult.cumulatedGridRechargeEnergy)));
|
let solarRechargeRatio = Math.round(100*(simulationResult.cumulatedSolarRechargeEnergy/(simulationResult.cumulatedSolarRechargeEnergy + simulationResult.cumulatedGridRechargeEnergy)));
|
||||||
|
|
||||||
|
let dailyDuration = parameters.dailyDistance / simulationResult.averageSpeed;
|
||||||
|
let dailyDurationHours = Math.floor(dailyDuration);
|
||||||
|
let dailyDurationMinutes = Math.round((dailyDuration - dailyDurationHours) * 60);
|
||||||
|
|
||||||
resultsContainer.querySelector('.result-info').innerHTML = `
|
resultsContainer.querySelector('.result-info').innerHTML = `
|
||||||
<p>Il faudra recharger le vhélio sur secteur environ ${simulationResult.gridChargeCount} fois sur l'année.</p>
|
<p>Il faudra recharger le vhélio sur secteur environ ${simulationResult.gridChargeCount} fois sur l'année.</p>
|
||||||
<p>Cela coûtera ${Math.round(totalConsumedGridPower/1000*averageKwhCost*100)/100}€ sur l'année.</p>
|
<p>Cela coûtera ${Math.round(totalConsumedGridPower/1000*averageKwhCost*100)/100}€ sur l'année. Le vhélio sera rechargé à ${solarRechargeRatio}% par le soleil, ${100-solarRechargeRatio}% sur secteur.</p>
|
||||||
<p>Le vhélio sera rechargé à ${solarRechargeRatio}% par le soleil, ${100-solarRechargeRatio}% sur secteur.</p>
|
<p><br/></p>
|
||||||
|
<p>Vitesse moyenne : ${Math.round(simulationResult.averageSpeed*10.0)/10.0} km/h (${Math.round(simulationResult.flatTerrainSpeed*10.0)/10.0} km/h sur plat, ${Math.round(simulationResult.uphillSpeed*10.0)/10.0} km/h en côte, ${Math.round(simulationResult.downhillSpeed*10.0)/10.0} km/h en descente)</p>
|
||||||
|
<p>Durée du trajet quotidien : ${dailyDurationHours}h ${dailyDurationMinutes}min. Distance annuelle : ${Math.round(simulationResult.cumulatedDistance)} km.</p>
|
||||||
`;
|
`;
|
||||||
//<p>${Math.round(100*(simulationResult.cumulatedSolarRechargeEnergy/simulationResult.vehicle.batteryEfficiency) / simulationResult.totalProducedSolarEnergy)}% de l'énergie produite par le panneau photovoltaïque sera utilisée pour recharger le vhélio.</p>
|
//<p>${Math.round(100*(simulationResult.cumulatedSolarRechargeEnergy/simulationResult.vehicle.batteryEfficiency) / simulationResult.totalProducedSolarEnergy)}% de l'énergie produite par le panneau photovoltaïque sera utilisée pour recharger le vhélio.</p>
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<p class="control is-expanded">
|
<p class="control is-expanded">
|
||||||
<input name="additional-weight" class="input" type="number" min="1" value="70"/>
|
<input name="additional-weight" class="input" type="number" min="1" value="50"/>
|
||||||
</p>
|
</p>
|
||||||
<p class="control">
|
<p class="control">
|
||||||
<a class="button is-static">kg</a>
|
<a class="button is-static">kg</a>
|
||||||
@ -160,12 +160,12 @@
|
|||||||
|
|
||||||
<div class="field is-horizontal">
|
<div class="field is-horizontal">
|
||||||
<div class="field-label is-normal">
|
<div class="field-label is-normal">
|
||||||
<label class="label">Vitesse moyenne (hors arrêts)</label>
|
<label class="label">Contrainte vitesse (circulation, etc.)</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<p class="control is-expanded">
|
<p class="control is-expanded">
|
||||||
<input name="average-speed" class="input" type="number" min="1" value="20"/>
|
<input name="speed-limit" class="input" type="number" min="1" value="30"/>
|
||||||
</p>
|
</p>
|
||||||
<p class="control">
|
<p class="control">
|
||||||
<a class="button is-static">km/h</a>
|
<a class="button is-static">km/h</a>
|
||||||
@ -173,6 +173,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field is-horizontal">
|
||||||
|
<div class="field-label is-normal">
|
||||||
|
<label class="label">Ratio de terrain plat</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field has-addons">
|
||||||
|
<p class="control is-expanded">
|
||||||
|
<input name="flat-ratio" class="input" type="number" min="0" max="100" value="75"/>
|
||||||
|
</p>
|
||||||
|
<p class="control">
|
||||||
|
<a class="button is-static">%</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
namespace Simulator {
|
namespace Simulator {
|
||||||
|
interface ConsumptionData {
|
||||||
|
motorEnergy: number;
|
||||||
|
humanEnergy: number;
|
||||||
|
averageSpeed: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class Vehicle {
|
export class Vehicle {
|
||||||
batteryCapacity: number;
|
batteryCapacity: number;
|
||||||
batteryEfficiency: number = 0.9;
|
batteryEfficiency: number = 0.9;
|
||||||
@ -12,12 +18,17 @@ namespace Simulator {
|
|||||||
additionalWeight: number = 0; // additional weight, not counting cyclist and empty vehicle weight, in kg
|
additionalWeight: number = 0; // additional weight, not counting cyclist and empty vehicle weight, in kg
|
||||||
|
|
||||||
humanPower: number = 100; // W
|
humanPower: number = 100; // W
|
||||||
averageSpeed: number = 20; // average speed in km/h, when the vehicle is moving (this is important, because driver does not provide power when stopped)
|
speedLimit: number = 20; // average speed in km/h, when the vehicle is moving (this is important, because driver does not provide power when stopped)
|
||||||
|
|
||||||
nominalMotorPower: number = 250; // W
|
nominalMotorPower: number = 250; // W
|
||||||
assistanceSpeedLimit: number = 25; // km/h
|
assistanceSpeedLimit: number = 25; // km/h
|
||||||
|
|
||||||
motorConsumption(distance: number, ascendingElevation: number): number {
|
consumption(distance: number, ascendingElevation: number, inOutConsumption: ConsumptionData) {
|
||||||
|
if(distance <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const g = 9.8;
|
const g = 9.8;
|
||||||
let totalWeight = this.emptyVehicleWeight + this.driverWeight + this.additionalWeight;
|
let totalWeight = this.emptyVehicleWeight + this.driverWeight + this.additionalWeight;
|
||||||
let potentialEnergy = totalWeight * g * ascendingElevation; // Ep = m*g*h (result in Joules)
|
let potentialEnergy = totalWeight * g * ascendingElevation; // Ep = m*g*h (result in Joules)
|
||||||
@ -25,32 +36,35 @@ namespace Simulator {
|
|||||||
|
|
||||||
// empirical measures
|
// empirical measures
|
||||||
let baseConsumption = 13; // in Wh/km, when human power is 0
|
let baseConsumption = 13; // in Wh/km, when human power is 0
|
||||||
let maxWeight = 300; // in kg
|
let additionalConsumptionPerKg = 0.01; // in Wh/km per kg of total vehicle weight (additional losses due to increased friction, mostly independent of speed)
|
||||||
let additionalConsumptionAtMaxWeight = 5; // in Wh/km (without accounting for ascending elevation, only accelerations and additional friction)
|
|
||||||
|
|
||||||
let weightRelatedConsumption = MathUtils.clamp(totalWeight * additionalConsumptionAtMaxWeight / maxWeight, 0, additionalConsumptionAtMaxWeight);
|
let requiredEnergy = Math.max(0, distance * (baseConsumption + totalWeight * additionalConsumptionPerKg) + potentialEnergy);
|
||||||
|
|
||||||
let motorPowerLimit = this.nominalMotorPower;
|
let motorPowerLimit = this.nominalMotorPower;
|
||||||
let tripDuration = (distance * (baseConsumption + weightRelatedConsumption) + potentialEnergy) / (motorPowerLimit + this.humanPower);
|
let tripDuration = Math.max(0.0001, requiredEnergy / (motorPowerLimit + this.humanPower));
|
||||||
let actualSpeed = distance / tripDuration;
|
let actualSpeed = distance / tripDuration;
|
||||||
console.log("Max vehicle speed, according to available power: " + (Math.round(actualSpeed*10)/10) + " km/h")
|
//console.log("Max vehicle speed, according to available power: " + (Math.round(actualSpeed*10)/10) + " km/h")
|
||||||
|
|
||||||
if(actualSpeed > this.assistanceSpeedLimit) {
|
if(actualSpeed > this.assistanceSpeedLimit) {
|
||||||
tripDuration = distance / this.assistanceSpeedLimit
|
let assistTripDuration = distance / this.assistanceSpeedLimit
|
||||||
motorPowerLimit = Math.max(0, ((distance * (baseConsumption + weightRelatedConsumption) + potentialEnergy) - tripDuration * this.humanPower) / tripDuration);
|
motorPowerLimit = Math.max(0, requiredEnergy/assistTripDuration - this.humanPower);
|
||||||
tripDuration = (distance * (baseConsumption + weightRelatedConsumption) + potentialEnergy) / (motorPowerLimit + this.humanPower);
|
if(motorPowerLimit + this.humanPower > 0)
|
||||||
|
tripDuration = requiredEnergy / (motorPowerLimit + this.humanPower);
|
||||||
actualSpeed = distance / tripDuration;
|
actualSpeed = distance / tripDuration;
|
||||||
console.log("Vehicle speed clamped by assistance speed limit, motor power limited to: " + Math.round(motorPowerLimit) + " W")
|
//console.log("Vehicle speed accounting for assistance speed limit: " + (Math.round(actualSpeed*10)/10) + " km/h (motor power limited to: " + Math.round(motorPowerLimit) + " W)")
|
||||||
}
|
}
|
||||||
|
|
||||||
if(actualSpeed > this.averageSpeed) {
|
if(actualSpeed > this.speedLimit) {
|
||||||
actualSpeed = this.averageSpeed;
|
actualSpeed = this.speedLimit;
|
||||||
tripDuration = distance / actualSpeed;
|
tripDuration = distance / actualSpeed;
|
||||||
|
motorPowerLimit = Math.max(0, requiredEnergy/tripDuration - this.humanPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
let humanEnergy = tripDuration * this.humanPower;
|
let humanEnergy = Math.max(requiredEnergy, tripDuration * this.humanPower);
|
||||||
|
|
||||||
return Math.max(motorPowerLimit * tripDuration, distance * (baseConsumption + weightRelatedConsumption) + potentialEnergy - humanEnergy);
|
inOutConsumption.motorEnergy += Math.max(motorPowerLimit * tripDuration, requiredEnergy - humanEnergy);
|
||||||
|
inOutConsumption.humanEnergy += humanEnergy;
|
||||||
|
inOutConsumption.averageSpeed += actualSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
solarPower(irradiance: number): number {
|
solarPower(irradiance: number): number {
|
||||||
@ -66,7 +80,7 @@ namespace Simulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class OutingPlanning {
|
export class OutingPlanning {
|
||||||
constructor(public dailyDistance: number, public dailyAscendingElevation: number) {
|
constructor(public dailyDistance: number, public dailyAscendingElevation: number, public flatTerrainRatio: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getOuting(dayOfWeek: number, hourOfDay: number, outing: Outing) {
|
getOuting(dayOfWeek: number, hourOfDay: number, outing: Outing) {
|
||||||
@ -95,6 +109,14 @@ namespace Simulator {
|
|||||||
cumulatedSolarRechargeEnergy: number; // Cumulated energy added to the battery from the solar panel, in Wh of battery charge (actual generated power is slightly higher due to losses)
|
cumulatedSolarRechargeEnergy: number; // Cumulated energy added to the battery from the solar panel, in Wh of battery charge (actual generated power is slightly higher due to losses)
|
||||||
totalProducedSolarEnergy: number; // Cumulated energy produced (used or unused), before accounting for the battery recharge efficiency.
|
totalProducedSolarEnergy: number; // Cumulated energy produced (used or unused), before accounting for the battery recharge efficiency.
|
||||||
cumulatedMotorConsumption: number; // Cumulated energy consumed by the motor, in Wh. In this simulation, this is equal to the energy drawn from the battery.
|
cumulatedMotorConsumption: number; // Cumulated energy consumed by the motor, in Wh. In this simulation, this is equal to the energy drawn from the battery.
|
||||||
|
cumulatedHumanEnergy: number;
|
||||||
|
|
||||||
|
cumulatedDistance: number;
|
||||||
|
|
||||||
|
flatTerrainSpeed: number;
|
||||||
|
uphillSpeed: number;
|
||||||
|
downhillSpeed: number;
|
||||||
|
averageSpeed: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function simulate(vehicle: Vehicle, solarIrradiance: number[], planning: OutingPlanning): SimulationResult {
|
export function simulate(vehicle: Vehicle, solarIrradiance: number[], planning: OutingPlanning): SimulationResult {
|
||||||
@ -106,12 +128,45 @@ namespace Simulator {
|
|||||||
cumulatedGridRechargeEnergy: 0,
|
cumulatedGridRechargeEnergy: 0,
|
||||||
cumulatedSolarRechargeEnergy: 0,
|
cumulatedSolarRechargeEnergy: 0,
|
||||||
totalProducedSolarEnergy: 0,
|
totalProducedSolarEnergy: 0,
|
||||||
cumulatedMotorConsumption: 0
|
cumulatedMotorConsumption: 0,
|
||||||
|
cumulatedHumanEnergy: 0,
|
||||||
|
|
||||||
|
cumulatedDistance: 0,
|
||||||
|
|
||||||
|
flatTerrainSpeed: 0,
|
||||||
|
uphillSpeed: 0,
|
||||||
|
downhillSpeed: 0,
|
||||||
|
averageSpeed: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
let remainingBatteryCharge = vehicle.batteryCapacity;
|
let remainingBatteryCharge = vehicle.batteryCapacity;
|
||||||
|
|
||||||
let outing: Outing = { distance: 0, ascendingElevation: 0 };
|
let outing: Outing = { distance: 0, ascendingElevation: 0 };
|
||||||
|
let consumption: ConsumptionData = { motorEnergy: 0, humanEnergy: 0, averageSpeed: 0 };
|
||||||
|
|
||||||
|
let flatTerrainRatio = MathUtils.clamp(planning.flatTerrainRatio, 0.0, 1.0);
|
||||||
|
if(planning.dailyAscendingElevation <= 0) flatTerrainRatio = 1.0;
|
||||||
|
|
||||||
|
let flatDistance = planning.dailyDistance * flatTerrainRatio;
|
||||||
|
consumption = { motorEnergy: 0, humanEnergy: 0, averageSpeed: 0 };
|
||||||
|
vehicle.consumption(flatDistance, 0, consumption);
|
||||||
|
result.flatTerrainSpeed = consumption.averageSpeed;
|
||||||
|
|
||||||
|
let uphillDistance = planning.dailyDistance * (1.0 - flatTerrainRatio) * 0.5;
|
||||||
|
consumption = { motorEnergy: 0, humanEnergy: 0, averageSpeed: 0 };
|
||||||
|
vehicle.consumption(uphillDistance, planning.dailyAscendingElevation, consumption);
|
||||||
|
result.uphillSpeed = consumption.averageSpeed;
|
||||||
|
|
||||||
|
let downhillDistance = planning.dailyDistance * (1.0 - flatTerrainRatio) * 0.5;
|
||||||
|
consumption = { motorEnergy: 0, humanEnergy: 0, averageSpeed: 0 };
|
||||||
|
vehicle.consumption(downhillDistance, -planning.dailyAscendingElevation, consumption);
|
||||||
|
result.downhillSpeed = consumption.averageSpeed;
|
||||||
|
|
||||||
|
let dailyTripDuration =
|
||||||
|
(flatDistance > 0 ? flatDistance / result.flatTerrainSpeed : 0)
|
||||||
|
+ (uphillDistance > 0 ? uphillDistance / result.uphillSpeed : 0)
|
||||||
|
+ (downhillDistance > 0 ? downhillDistance / result.downhillSpeed : 0);
|
||||||
|
result.averageSpeed = planning.dailyDistance / dailyTripDuration;
|
||||||
|
|
||||||
for(let day = 0; day < 365; ++day) {
|
for(let day = 0; day < 365; ++day) {
|
||||||
for(let hour = 0; hour < 24; ++hour) {
|
for(let hour = 0; hour < 24; ++hour) {
|
||||||
@ -119,14 +174,20 @@ namespace Simulator {
|
|||||||
|
|
||||||
planning.getOuting(day % 7, hour, outing);
|
planning.getOuting(day % 7, hour, outing);
|
||||||
|
|
||||||
let consumption = outing.distance > 0 ? vehicle.motorConsumption(outing.distance, outing.ascendingElevation) : 0;
|
consumption.motorEnergy = 0; consumption.humanEnergy = 0; consumption.averageSpeed = 0;
|
||||||
|
|
||||||
|
vehicle.consumption(outing.distance * flatTerrainRatio, 0, consumption);
|
||||||
|
vehicle.consumption(outing.distance * (1.0 - flatTerrainRatio) * 0.5, outing.ascendingElevation, consumption);
|
||||||
|
vehicle.consumption(outing.distance * (1.0 - flatTerrainRatio) * 0.5, -outing.ascendingElevation, consumption);
|
||||||
|
result.cumulatedDistance += outing.distance;
|
||||||
|
|
||||||
let production = vehicle.solarPower(solarIrradiance[hourIdx]) * 1.0; // produced energy in Wh is equal to power (W) multiplied by time (h)
|
let production = vehicle.solarPower(solarIrradiance[hourIdx]) * 1.0; // produced energy in Wh is equal to power (W) multiplied by time (h)
|
||||||
|
|
||||||
result.totalProducedSolarEnergy += production;
|
result.totalProducedSolarEnergy += production;
|
||||||
let solarCharge = production * vehicle.batteryEfficiency;
|
let solarCharge = production * vehicle.batteryEfficiency;
|
||||||
|
|
||||||
// TODO: we should keep a margin because real users will recharge before they reach the bare minimum required for an outing
|
// TODO: we should keep a margin because real users will recharge before they reach the bare minimum required for an outing
|
||||||
remainingBatteryCharge += solarCharge - consumption;
|
remainingBatteryCharge += solarCharge - consumption.motorEnergy;
|
||||||
|
|
||||||
let fullGridRecharge = false;
|
let fullGridRecharge = false;
|
||||||
if(remainingBatteryCharge > vehicle.batteryCapacity) {
|
if(remainingBatteryCharge > vehicle.batteryCapacity) {
|
||||||
@ -142,7 +203,7 @@ namespace Simulator {
|
|||||||
result.gridChargeCount += 1;
|
result.gridChargeCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.cumulatedMotorConsumption += consumption;
|
result.cumulatedMotorConsumption += consumption.motorEnergy;
|
||||||
result.cumulatedSolarRechargeEnergy += solarCharge;
|
result.cumulatedSolarRechargeEnergy += solarCharge;
|
||||||
|
|
||||||
result.batteryLevel[hourIdx] = fullGridRecharge ? 0 : remainingBatteryCharge;
|
result.batteryLevel[hourIdx] = fullGridRecharge ? 0 : remainingBatteryCharge;
|
||||||
|
Loading…
Reference in New Issue
Block a user