Commit eff5d429 authored by Julian Zobel's avatar Julian Zobel 🦄
Browse files

Merge branch 'master' into 'cherry-pick-7698d9d7'

# Conflicts:
#   src/de/tud/kom/p2psim/impl/analyzer/metric/output/MetricOutputDAO.java
#   src/de/tud/kom/p2psim/impl/util/db/dao/DAO.java
parents 1c7f20ec 37020b44
......@@ -29,7 +29,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.tud.kom.p2psim.api.simengine.SimulatorObserver;
import de.tud.kom.p2psim.impl.simengine.Simulator;
......@@ -94,7 +95,7 @@ public class DefaultMonitor implements MonitorComponent, EventHandler,
public void log(Class<?> subject, Level level, String msg, Object... data) {
Logger log = loggers.get(subject);
if (log == null) {
log = Logger.getLogger(subject);
log = LogManager.getLogger(subject);
loggers.put(subject, log);
}
switch (level) {
......@@ -143,7 +144,7 @@ public class DefaultMonitor implements MonitorComponent, EventHandler,
public void setTableName(String tableName) {
System.out.println("Table Name is set to: " + tableName);
if (tableName != null && !tableName.equals("")) {
DAO.database = tableName;
DAO.setDatabase(tableName);
}
}
......@@ -215,7 +216,7 @@ public class DefaultMonitor implements MonitorComponent, EventHandler,
analyzer.stop(output);
}
output.write("*******************************************************\n");
// output.close();
output.close();
} catch (IOException e) {
throw new AssertionError();
}
......
......@@ -25,9 +25,11 @@ import java.util.Random;
import java.util.Vector;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.Battery;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.api.energy.EnergyModel;
import de.tud.kom.p2psim.api.scenario.ConfigurationException;
import de.tud.kom.p2psim.impl.energy.models.ComponentBasedEnergyModel;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
......@@ -60,6 +62,10 @@ public class EnergyModelFactory implements HostComponentFactory {
*/
private boolean configurationsUsed = false;
private boolean useRandomBatteryStartConfiguration = false;
private double minimumStartEnergyLevel = 0.3;
private Battery batteryModel = new SimpleBattery(186480000, 186480000);
/**
......@@ -80,15 +86,23 @@ public class EnergyModelFactory implements HostComponentFactory {
}
configurationsUsed = true;
Battery bat;
if(useRandomBatteryStartConfiguration)
{
// clone the battery from the provided model
// FIXME Different Capacities for different nodes.
double percentageOfFullBattery = (1 - random.nextDouble());
if(percentageOfFullBattery < 0.3)
percentageOfFullBattery = 0.3;
double initialEnergy = 186480000 * percentageOfFullBattery;
Battery bat = new SimpleBattery(186480000, initialEnergy);
// Battery bat = batteryModel.clone();
EnergyModel em = new ModularEnergyModel(host, bat);
if(percentageOfFullBattery < minimumStartEnergyLevel)
percentageOfFullBattery = minimumStartEnergyLevel;
double initialEnergy = batteryModel.getMaximumEnergy() * percentageOfFullBattery;
bat = batteryModel.copy(initialEnergy);
}
else {
bat = batteryModel.copy(batteryModel.getMaximumEnergy());
}
EnergyModel em = new ComponentBasedEnergyModel(host, bat);
for (EnergyConfiguration config : energyConfigurations) {
em.registerComponent(config.getConfiguredEnergyComponent(host));
......@@ -128,5 +142,20 @@ public class EnergyModelFactory implements HostComponentFactory {
energyConfigurations.add(energyConfig);
}
public void setMinimumStartEnergyLevel(double level) {
if(level > 1.0) {
this.minimumStartEnergyLevel = 1.0;
}
else if(level < 0.0) {
this.minimumStartEnergyLevel = 0.0;
}
else {
this.minimumStartEnergyLevel = level;
}
}
public void setUseRandomBatteryStartConfiguration(boolean randomStart) {
this.useRandomBatteryStartConfiguration = randomStart;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy;
import de.tud.kom.p2psim.api.energy.Battery;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/**
* Extension to the basic battery implementation, enables to charge the battery.
*
*
* @author Julian Zobel
* @version 1.0, 21.09.2018
*/
public class RechargeableBattery extends SimpleBattery {
@XMLConfigurableConstructor({ "capacity", "initialEnergy" })
public RechargeableBattery(double capacity, double initialEnergy) {
super(capacity, initialEnergy);
}
/**
* Charge the battery with the given amount in <b>uJ</b>
*
* @param charge
*/
public void chargeBattery(double charge) {
if(currentEnergy + charge >= capacity) {
currentEnergy = capacity;
}
else {
currentEnergy += charge;
}
}
@Override
public void setToMaximumLoad() {
currentEnergy = capacity;
}
@Override
public Battery copy(double initialEnergy) {
return new RechargeableBattery(capacity / 1000000, initialEnergy / 1000000);
}
@Override
public String toString() {
return "Rechargeable Battery ["+getCurrentPercentage()+"%] ["+getCurrentEnergy()+"/"+getMaximumEnergy()+"]";
}
}
......@@ -20,6 +20,7 @@
package de.tud.kom.p2psim.impl.energy;
import de.tud.kom.p2psim.api.energy.Battery;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
/**
......@@ -31,13 +32,12 @@ import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
*/
public class SimpleBattery implements Battery {
private double capacity;
protected final double capacity;
private double initialEnergy;
protected final double initialEnergy;
private double currentEnergy;
protected double currentEnergy;
private boolean isEmpty = false;
/**
* Create a new battery with the given initial energy and total capacity in
......@@ -47,15 +47,15 @@ public class SimpleBattery implements Battery {
* @param initalEnergy
*/
@XMLConfigurableConstructor({ "capacity", "initialEnergy" })
public SimpleBattery(double capacity, double initalEnergy) {
public SimpleBattery(double capacity, double initialEnergy) {
this.capacity = capacity * 1000000;
this.initialEnergy = initalEnergy * 1000000;
this.currentEnergy = initalEnergy * 1000000;
this.initialEnergy = initialEnergy * 1000000;
this.currentEnergy = initialEnergy * 1000000;
}
@Override
public double getCurrentPercentage() {
if (isEmpty) {
if (isEmpty()) {
return 0.0;
}
double percent = 100.0 * currentEnergy / capacity;
......@@ -64,8 +64,8 @@ public class SimpleBattery implements Battery {
}
@Override
public double getCurrentEnergyLevel() {
if (isEmpty) {
public double getCurrentEnergy() {
if (isEmpty()) {
return 0.0;
}
return currentEnergy;
......@@ -76,22 +76,15 @@ public class SimpleBattery implements Battery {
return capacity - currentEnergy;
}
@Override
public void reset() {
currentEnergy = initialEnergy;
isEmpty = false;
}
@Override
public void setToPercentage(double percentage) {
currentEnergy = (capacity / 100.0) * percentage;
isEmpty = false;
}
@Override
public void consumeEnergy(double energy) {
if (isEmpty || energy >= currentEnergy) {
isEmpty = true;
if ( energy >= currentEnergy) {
currentEnergy = 0;
} else {
currentEnergy = currentEnergy - energy;
}
......@@ -99,7 +92,10 @@ public class SimpleBattery implements Battery {
@Override
public boolean isEmpty() {
return isEmpty;
if(currentEnergy == 0)
return true;
return false;
}
@Override
......@@ -107,4 +103,22 @@ public class SimpleBattery implements Battery {
return new SimpleBattery(capacity / 1000000, initialEnergy / 1000000);
}
@Override
public double getMaximumEnergy() {
return initialEnergy;
}
@Override
public boolean isFullyCharged() {
if(currentEnergy == initialEnergy) {
return true;
}
return false;
}
@Override
public Battery copy(double initialEnergy) {
return new SimpleBattery(capacity / 1000000, initialEnergy / 1000000);
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy;
import de.tud.kom.p2psim.impl.topology.component.UAVTopologyComponent;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.EventHandler;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.component.HostComponent;
import de.tudarmstadt.maki.simonstrator.api.component.HostComponentFactory;
import de.tudarmstadt.maki.simonstrator.api.uavsupport.callbacks.BatteryReplacementCallback;
/**
* Ground-based charger for UAVs. Replaces the battery completely, i.e.,
* sets battery capacity to full levels, but requires some time to do so.
*
*
* @author Julian Zobel
* @version 1.0, 21.09.2018
*/
public class UAVReplacementCharger implements HostComponent {
private Host host;
private long replacementDuration;
public UAVReplacementCharger(Host host, long replacementDuration) {
this.host = host;
this.replacementDuration = replacementDuration;
}
/**
* Charge a UAV by replacing the battery (i.e. reset to full battery levels). Replacement takes some time.
* The UAV is informed about the full replacement when it is finished by a callback.
*
* @param uav
* @param cb
*/
public void charge(UAVTopologyComponent uav, BatteryReplacementCallback cb) {
Event.scheduleWithDelay(replacementDuration, new EventHandler() {
@Override
public void eventOccurred(Object content, int type) {
replacementComplete(uav, cb);
}
}, null, 0);
}
/**
* When this is called (after the replacement duration) the UAV's battery is set
* to full level/max capacity.
*
* @param uav
* @param cb
*/
protected void replacementComplete(UAVTopologyComponent uav, BatteryReplacementCallback cb) {
uav.getBattery().setToMaximumLoad();
cb.rechargeComplete();
}
@Override
public void initialize() {
// TODO Auto-generated method stub
}
@Override
public void shutdown() {
throw new UnsupportedOperationException("Charger shutdown not supported!");
}
@Override
public Host getHost() {
return host;
}
public static class Factory implements HostComponentFactory {
private long replacementDuration;
/**
* Duration of the battery replacement in SECONDS
* @param replacementDuration
*/
public void setReplacementDuration(long replacementDuration) {
this.replacementDuration = replacementDuration;
}
@Override
public HostComponent createComponent(Host host) {
return new UAVReplacementCharger(host, replacementDuration);
}
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.energy.EnergyComponent;
// Interface Tag
public interface ActuatorComponent extends EnergyComponent {
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy.components;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
public class MotorCharacteristic {
private final double thrust;
private final double current;
@XMLConfigurableConstructor({ "thrust", "current" })
public MotorCharacteristic(double thrust, double current) {
this.thrust = thrust;
this.current = current;
}
public double getCurrent() {
return current;
}
public double getThrust() {
return thrust;
}
@Override
public String toString() {
return "["+ thrust + "N @ " + current + "A]";
}
}
......@@ -18,11 +18,12 @@
*
*/
package de.tud.kom.p2psim.impl.energy;
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyComponent;
import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tudarmstadt.maki.simonstrator.api.Event;
import de.tudarmstadt.maki.simonstrator.api.Time;
......@@ -66,8 +67,10 @@ public class OneStateEnergyComponent implements EnergyComponent {
@Override
public void eventOccurred(Object content, int type) {
if (isOn()) {
energyModel.switchedState(this, state, state, Time.SECOND);
if (energyModel.turnOn(this)) {
double consumedEnergy = state.getEnergyConsumption() * Time.SECOND;
energyModel.componentConsumedEnergy(this, consumedEnergy);
if (energyModel.componentCanBeActivated(this)) {
Event.scheduleWithDelay(Time.SECOND, this, null, 0);
} else {
this.turnOff();
......@@ -81,8 +84,9 @@ public class OneStateEnergyComponent implements EnergyComponent {
}
@Override
public void turnOff() {
public boolean turnOff() {
this.on = false;
return true;
}
@Override
......
......@@ -18,7 +18,7 @@
*
*/
package de.tud.kom.p2psim.impl.energy;
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyCommunicationComponent;
......@@ -26,9 +26,11 @@ import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyModel;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
import de.tudarmstadt.maki.simonstrator.api.Time;
import de.tudarmstadt.maki.simonstrator.api.Monitor.Level;
public class SmartphoneCellularCommunicationEnergyComponent implements
......@@ -87,11 +89,12 @@ EnergyCommunicationComponent {
}
@Override
public void turnOff() {
public boolean turnOff() {
if (!currentState.equals(IDLE)) {
doStateChange(IDLE);
}
tailCounter++;
return true;
}
@Override
......@@ -101,7 +104,7 @@ EnergyCommunicationComponent {
@Override
public boolean isOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
doFakeStateChange();
return true;
}
......@@ -138,8 +141,8 @@ EnergyCommunicationComponent {
+ " after spending "
+ (timeInTailState / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel
.switchedState(this, currentState, null, timeInTailState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeInTailState));
tailCounter++;
currentState = IDLE;
lastStateChange = Simulator.getCurrentTime();
......@@ -160,7 +163,7 @@ EnergyCommunicationComponent {
* message. However, the energy for the ramp state before sending is
* consumed.
*/
energyModel.switchedState(this, RAMP_TX, null, RAMP_TX_DURATION);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RAMP_TX, RAMP_TX_DURATION));
} else {
assert currentState.equals(TAIL_RX) || currentState.equals(TAIL_TX);
......@@ -175,15 +178,16 @@ EnergyCommunicationComponent {
+ " after spending "
+ (timeInTailState / (double) Simulator.SECOND_UNIT)
+ " sec there before starting a transmission.");
energyModel
.switchedState(this, currentState, null, timeInTailState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeInTailState));
tailCounter++;
}
/*
* Consume the energy for the transmission of data.
*/
energyModel.switchedState(this, TX, null, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(TX, duration));
Monitor.log(SmartphoneCellularCommunicationEnergyComponent.class, Level.DEBUG, Simulator.getFormattedTime(Simulator.getCurrentTime())
+ " "
+ ((EnergyModel) energyModel).getHost().getHostId()
......@@ -213,7 +217,8 @@ EnergyCommunicationComponent {
* message. However, the energy for the ramp state before receiving
* is consumed.
*/
energyModel.switchedState(this, RAMP_RX, null, RAMP_RX_DURATION);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RAMP_RX, RAMP_RX_DURATION));
} else {
assert currentState.equals(TAIL_RX) || currentState.equals(TAIL_TX);
......@@ -228,14 +233,16 @@ EnergyCommunicationComponent {
+ " after spending "
+ (timeInTailState / (double) Simulator.SECOND_UNIT)
+ " sec there before receiving a message.");
energyModel
.switchedState(this, currentState, null, timeInTailState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeInTailState));
tailCounter++;
}
/*
* Consume the energy for the receiption of data.
*/
energyModel.switchedState(this, RX, null, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RX, duration));
Monitor.log(SmartphoneCellularCommunicationEnergyComponent.class, Level.DEBUG,Simulator.getCurrentTime()
+ " "
+ ((EnergyModel) energyModel).getHost().getHostId()
......@@ -265,8 +272,9 @@ EnergyCommunicationComponent {
+ " uJ in State " + currentState.getName() + " after spending "
+ (timeSpentInState / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
if(!currentState.equals(TAIL_RX) && !currentState.equals(TAIL_TX))
lastStateChange = Simulator.getCurrentTime();
......
......@@ -18,7 +18,7 @@
*
*/
package de.tud.kom.p2psim.impl.energy;
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyCommunicationComponent;
......@@ -26,6 +26,7 @@ import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyModel;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tud.kom.p2psim.impl.simengine.Simulator;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Monitor;
......@@ -88,15 +89,16 @@ public class SmartphoneCommunicationEnergyComponent implements
}
@Override
public void turnOff() {
public boolean turnOff() {
if (!currentState.equals(OFF)) {
doStateChange(OFF);
}
return true;
}
@Override
public boolean turnOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
if (!currentState.equals(IDLE)) {
doStateChange(IDLE);
}
......@@ -138,8 +140,9 @@ public class SmartphoneCommunicationEnergyComponent implements
+ (SEND.getEnergyConsumption() * (duration/ (double) Simulator.SECOND_UNIT))
+ " uJ in State " + SEND.getName() + " after spending "
+ (duration / (double) Simulator.SECOND_UNIT) + " sec there.");
energyModel.switchedState(this, SEND, null,
duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(SEND, duration));
}
@Override
......@@ -158,8 +161,9 @@ public class SmartphoneCommunicationEnergyComponent implements
+ " after spending "
+ (duration / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel.switchedState(this, RECEIVE, null,
duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RECEIVE, duration));
}
public void doFakeStateChange() {
......@@ -180,8 +184,8 @@ public class SmartphoneCommunicationEnergyComponent implements
+ " after spending "
+ (timeSpentInState / (double) Simulator.SECOND_UNIT)
+ " sec there.");
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastStateChange = Simulator.getCurrentTime();
}
......
......@@ -18,13 +18,14 @@
*
*/
package de.tud.kom.p2psim.impl.energy;
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyCommunicationComponent;
import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Time;
......@@ -86,15 +87,16 @@ public class StateEnergyCommunicationComponent implements
}
@Override
public void turnOff() {
public boolean turnOff() {
if (!currentState.equals(OFF)) {
doStateChange(OFF);
}
return true;
}
@Override
public boolean turnOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
if (!currentState.equals(IDLE)) {
doStateChange(IDLE);
}
......@@ -111,8 +113,7 @@ public class StateEnergyCommunicationComponent implements
private void doStateChange(EnergyState newState) {
long timeSpentInState = Time.getCurrentTime() - lastStateChange;
timeSpentInState = Math.max(0, timeSpentInState);
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastStateChange = Time.getCurrentTime();
}
......@@ -134,7 +135,7 @@ public class StateEnergyCommunicationComponent implements
doStateChange(RECV);
// we do this change manually, because we can save the event for the end
// receive!
energyModel.switchedState(this, RECV, IDLE, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(RECV, duration));
currentState = IDLE;
lastStateChange = Time.getCurrentTime() + duration;
}
......@@ -146,7 +147,7 @@ public class StateEnergyCommunicationComponent implements
doStateChange(SEND);
// we do this change manually, because we can save the event for the end
// receive!
energyModel.switchedState(this, SEND, IDLE, duration);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(SEND, duration));
currentState = IDLE;
lastStateChange = Time.getCurrentTime() + duration;
}
......
/*
* Copyright (c) 2005-2010 KOM � Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.energy.Battery;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tudarmstadt.maki.simonstrator.api.Time;
/**
* Energy component for actuators, representing the electrical consumers of actuators.
* This models uses several states, that define the used energy.
*
* @author Julian Zobel
* @version 1.0, 11.09.2018
*/
public class StatefulActuatorComponent implements ActuatorComponent {
/**
* States supported by this energy component
*
* TODO More states reflecting a more accurate energy consumption?
*/
public final EnergyState OFF, FLY, MAX;
private EnergyState currentState;
private EnergyEventListener energyModel;
private long lastEnergyConsumationEvent;
private double actuatorLoad;
public StatefulActuatorComponent(int numberOfActuators, double volt, double hoverAmp, double maxAmp) {
OFF = new DefaultEnergyState("OFF", 0);
FLY = new DefaultEnergyState("FLY", numberOfActuators * (hoverAmp * volt) * Battery.uJconverison);
MAX = new DefaultEnergyState("MAX", numberOfActuators * (maxAmp * volt) * Battery.uJconverison);
this.currentState = OFF;
this.lastEnergyConsumationEvent = Time.getCurrentTime();
this.actuatorLoad = 0;
}
public void doStateChange(EnergyState newState) {
long timeSpentInState = Time.getCurrentTime() - lastEnergyConsumationEvent;
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastEnergyConsumationEvent = Time.getCurrentTime();
}
@Override
public double calculateEnergyConsumation(EnergyState state, long timeInState) {
if(state.equals(FLY)) {
double consumationDelta = MAX.getEnergyConsumption() - FLY.getEnergyConsumption();
double consumation = FLY.getEnergyConsumption() + consumationDelta * actuatorLoad;
return consumation * ( (double) timeInState / (double) Time.SECOND);
}
else
return state.getEnergyConsumption() * ( (double) timeInState / (double) Time.SECOND);
}
public void useActuator(double load) {
if(load < 0 || load > 1.0) {
throw new AssertionError("Actuator load must be between 0 and 1!");
}
else {
this.actuatorLoad = load;
doStateChange(FLY);
}
}
/**
* Estimates the energy consumption based on a given load.
* @param load: Actuator load between 0.0 and 1.0
* @return Energy consumption in J/s
*/
public double estimateEnergyConsumptionWatt(double load) {
double consumationDelta = MAX.getEnergyConsumption() - FLY.getEnergyConsumption();
double estimation = FLY.getEnergyConsumption() + consumationDelta * load;
// System.out.println("MAX " + ((MAX.getEnergyConsumption() / 14.8) / Battery.uJconverison));
// System.out.println("MIN" + ((FLY.getEnergyConsumption() / 14.8) / Battery.uJconverison));
// System.out.println(load);
// this estimation is in uJ, but has to return J, thus, do conversion
return estimation / Battery.uJconverison;
}
@Override
public void eventOccurred(Object content, int type) {
// TODO Auto-generated method stub
}
@Override
public ComponentType getType() {
return ComponentType.ACTUATOR;
}
@Override
public boolean turnOff() {
doStateChange(OFF);
return true;
}
@Override
public boolean turnOn() {
if (isAvailable()) {
if (currentState.equals(OFF)) {
doStateChange(FLY);
}
return true;
}
return false;
}
public boolean isAvailable() {
if (energyModel.componentCanBeActivated(this))
return true;
return false;
}
@Override
public boolean isOn() {
if(!currentState.equals(OFF) && isAvailable())
{
return true;
}
return false;
}
@Override
public void setEnergyEventListener(EnergyEventListener listener) {
energyModel = listener;
}
public EnergyState getCurrentState() {
return currentState;
}
}
/*
* Copyright (c) 2005-2010 KOM � Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy.components;
import java.util.Comparator;
import java.util.LinkedList;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tudarmstadt.maki.simonstrator.api.Time;
/**
* Component for devices that provide thrust, such as electrical motors for UAV propulsion.
* Is configured by {@link MotorCharacteristic}s with a given thrust (N) and a given current (A).
* Values in between given characteristics are calculated by linear interpolation.
*
* @author Julian Zobel
* @version 1.0, 05.03.2019
*/
public class StatelessActuatorComponent implements ActuatorComponent {
public enum componentState {OFF, ON}
private componentState state;
private EnergyEventListener energyModel;
private long lastEnergyConsumationTime;
private double volts;
private final double uJconversionFactor = 1000000;
private final int numberOfActuators;
private double thrust;
private double amps;
private EnergyState energyState;
private LinkedList<MotorCharacteristic> characteristics = new LinkedList<>();
public StatelessActuatorComponent(int numberOfActuators, double volt) {
this.volts = volt;
this.numberOfActuators = numberOfActuators;
this.state = componentState.OFF;
this.lastEnergyConsumationTime = Time.getCurrentTime();
thrust = 0;
amps = 0;
energyState = new DefaultEnergyState("OFF", 0);
}
/**
* Get the maximum thrust provided by this component.
* @return
*/
public double getMaxThrust() {
return characteristics.getLast().getThrust() * numberOfActuators;
}
/**
* Set the new energy state and calculate the energy consumption from the last state
*/
private void setEnergyState() {
// set the new energy state
EnergyState newState;
if(state == componentState.ON) {
newState = new DefaultEnergyState("Actuator", numberOfActuators * (amps * volts) * uJconversionFactor);
}
else {
newState = new DefaultEnergyState("OFF", 0);
}
// calculate energy consumption for the previous state
long timeSpentInState = Time.getCurrentTime() - lastEnergyConsumationTime;
double cons = calculateEnergyConsumation(energyState, timeSpentInState);
energyModel.componentConsumedEnergy(this, cons);
// set new state
energyState = newState;
lastEnergyConsumationTime = Time.getCurrentTime();
}
/**
* Request a given amount of thrust to be provided from this component. If the amount is less than the minimum
* or more than the maximum, the minimum or maximum thrust values, respectively, are enforced.
*
* @param targetThrust
* @return The amount of thrust this component now generates.
*/
public double requestThrust(double targetThrust) {
if(targetThrust == 0 || targetThrust <= numberOfActuators * characteristics.getFirst().getThrust()) {
setLoad(characteristics.getFirst());
}
else if(targetThrust >= numberOfActuators * characteristics.getLast().getThrust()) {
setLoad(characteristics.getLast());
}
else {
calculateAndSetThrustRelatedAmpereDraw(targetThrust);
}
return this.thrust;
}
/**
*
* @param targetThrust
* @return The power consumption for the target thrust in Watt
*/
public double estimatePowerConsumptionWatt(double targetThrust) {
if(targetThrust == 0 || targetThrust <= numberOfActuators * characteristics.getFirst().getThrust()) {
// not allowed
return Double.NaN;
}
else if(targetThrust > numberOfActuators * characteristics.getLast().getThrust()) {
// not allowed
return Double.NaN;
}
else {
double amps = approximateAmpereDraw(targetThrust);
//System.out.println(amps);
return numberOfActuators * amps * volts;
}
}
/**
* Given an amount of thrust between the minimum and maximum values, the required current
* to provide this amount of thrust is calculated by linear interpolation by the nearest lower
* and upper {@link MotorCharacteristic}s.
*
* @param targetThrust
* @return the approximated ampere draw
*/
private double approximateAmpereDraw(double targetThrust) {
MotorCharacteristic lower = null, upper = null;
// find the lower and upper bounding characteristics
for (MotorCharacteristic ch : characteristics) {
//
if(ch.getThrust() * numberOfActuators == targetThrust) {
return ch.getCurrent();
}
else {
// list is sorted, lower bound is the biggest that is lower
if(ch.getThrust() * numberOfActuators < targetThrust) {
lower = ch;
}
// the first that is greater is used as upper bound
else if(ch.getThrust() * numberOfActuators > targetThrust) {
upper = ch;
break;
}
}
}
if(upper == null || lower == null) {
throw new UnsupportedOperationException("Lower or upper bounds cannot be null");
}
if(upper.getThrust() * numberOfActuators < targetThrust || lower.getThrust() * numberOfActuators > targetThrust) {
throw new UnsupportedOperationException("Lower or upper bound do not match");
}
/*
* Calculate the approximated current with the upper and lower bounds:
* Amp_approx = Amp_lower + (T_target - T_lower)/(T_upper - T_lower) * (Amp_upper - Amp_lower)
*/
double delta = (targetThrust - (lower.getThrust() * numberOfActuators))/(numberOfActuators * (upper.getThrust() - lower.getThrust()));
return lower.getCurrent() + delta * (upper.getCurrent() - lower.getCurrent());
}
/**
* Approximates the ampere draw required forthe requested thrust
*
* Target thrust should be strictly within the possible thrust limits
*
*/
private void calculateAndSetThrustRelatedAmpereDraw(double targetThrust) {
double calculatedAmps = approximateAmpereDraw(targetThrust);
setLoad(targetThrust, calculatedAmps);
}
private void setLoad(double thrust, double amps) {
this.thrust = thrust;
this.amps = amps;
setEnergyState();
}
private void setLoad(MotorCharacteristic ch) {
this.thrust = ch.getThrust();
this.amps = ch.getCurrent();
setEnergyState();
}
/**
* Add a {@link MotorCharacteristic} for this motor.
*
* @param c
*/
public void addChar(MotorCharacteristic c) {
characteristics.add(c);
// sort the characteristics starting from low to high thrust
characteristics.sort(new Comparator<MotorCharacteristic>() {
@Override
public int compare(MotorCharacteristic o1,
MotorCharacteristic o2) {
return (int) (o1.getThrust() - o2.getThrust());
}
});
}
@Override
public void eventOccurred(Object content, int type) {
// TODO Auto-generated method stub
}
@Override
public ComponentType getType() {
return ComponentType.ACTUATOR;
}
@Override
public boolean turnOff() {
this.thrust = 0;
this.amps = 0;
this.state = componentState.OFF;
setEnergyState();
return true;
}
@Override
public boolean turnOn() {
if (isAvailable()) {
if(this.state != componentState.ON) {
this.state = componentState.ON;
requestThrust(0);
}
return true;
}
return false;
}
public boolean isAvailable() {
if (energyModel.componentCanBeActivated(this)) {
return true;
}
return false;
}
@Override
public boolean isOn() {
if(this.state != componentState.OFF && isAvailable()) {
return true;
}
return false;
}
@Override
public void setEnergyEventListener(EnergyEventListener listener) {
energyModel = listener;
}
public EnergyState getCurrentState() {
return energyState;
}
}
......@@ -18,20 +18,21 @@
*
*/
package de.tud.kom.p2psim.impl.energy;
package de.tud.kom.p2psim.impl.energy.components;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyCommunicationComponent;
import de.tud.kom.p2psim.api.energy.EnergyEventListener;
import de.tud.kom.p2psim.api.energy.EnergyState;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.DefaultEnergyState;
import de.tudarmstadt.maki.simonstrator.api.Message;
import de.tudarmstadt.maki.simonstrator.api.Time;
/**
* This is the implementation of a communication component that does not care
* about a state - it just consumes energy as soon as something is being sent.
* In the context of the {@link ModularEnergyModel} we mimic a state-aware
* In the context of the {@link StateSwitchingEnergyModel} we mimic a state-aware
* behavior. Please take a look at the comment in the Constructor if your
* analyzers seem to return odd results with this component...
*
......@@ -110,15 +111,16 @@ public class StatelessCommunicationComponent implements
}
@Override
public void turnOff() {
public boolean turnOff() {
if (!currentState.equals(OFF)) {
doStateChange(OFF);
}
return true;
}
@Override
public boolean turnOn() {
if (energyModel.turnOn(this)) {
if (energyModel.componentCanBeActivated(this)) {
if (!currentState.equals(IDLE)) {
doStateChange(IDLE);
}
......@@ -134,8 +136,7 @@ public class StatelessCommunicationComponent implements
private void doStateChange(EnergyState newState) {
long timeSpentInState = Time.getCurrentTime() - lastStateChange;
energyModel.switchedState(this, currentState, newState,
timeSpentInState);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(currentState, timeSpentInState));
currentState = newState;
lastStateChange = Time.getCurrentTime();
}
......@@ -165,7 +166,7 @@ public class StatelessCommunicationComponent implements
doStateChange(ON);
// switch back to IDLE with fake timeHP
energyModel.switchedState(this, ON, IDLE, timeHP);
energyModel.componentConsumedEnergy(this, calculateEnergyConsumation(ON, timeHP));
currentState = IDLE;
lastStateChange = Time.getCurrentTime();
}
......
......@@ -23,7 +23,7 @@ package de.tud.kom.p2psim.impl.energy.configs;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.ComponentType;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.impl.energy.OneStateEnergyComponent;
import de.tud.kom.p2psim.impl.energy.components.OneStateEnergyComponent;
/**
* This class creates an Energy Component for basic Energy Consumption. It
......
......@@ -23,7 +23,7 @@ package de.tud.kom.p2psim.impl.energy.configs;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.SmartphoneCellularCommunicationEnergyComponent;
import de.tud.kom.p2psim.impl.energy.components.SmartphoneCellularCommunicationEnergyComponent;
public class CellularTimeBased implements
EnergyConfiguration<SmartphoneCellularCommunicationEnergyComponent> {
......
......@@ -24,7 +24,7 @@ import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.EnergyCommunicationComponent;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.StatelessCommunicationComponent;
import de.tud.kom.p2psim.impl.energy.components.StatelessCommunicationComponent;
/**
* This is a Message-Based {@link EnergyCommunicationComponent}-creating
......
......@@ -23,7 +23,7 @@ package de.tud.kom.p2psim.impl.energy.configs;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.api.linklayer.mac.PhyType;
import de.tud.kom.p2psim.impl.energy.StateEnergyCommunicationComponent;
import de.tud.kom.p2psim.impl.energy.components.StateEnergyCommunicationComponent;
/**
* This class contains the measured values from the Nexus One in the AdHoc Mode.
......
/*
* Copyright (c) 2005-2010 KOM � Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy.configs;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.impl.energy.components.StatefulActuatorComponent;
/**
* Energy Configuration for {@link StatefulActuatorComponent}s.
*
* @author Julian Zobel
* @version 1.0, 11.09.2018
*/
public class StatefulActuatorConfiguration implements EnergyConfiguration<StatefulActuatorComponent> {
private int numberOfActuators;
private double volt;
private double hoverAmp; // in ampere
private double flyAmp; // in ampere
@Override
public StatefulActuatorComponent getConfiguredEnergyComponent(SimHost host) {
return new StatefulActuatorComponent(numberOfActuators, volt, hoverAmp, flyAmp);
}
@Override
public String getHelp() {
return "Fix actuator energy consumption config";
}
@Override
public boolean isWellConfigured() {
if(numberOfActuators >= 1 && volt > 0
&& hoverAmp > 0 && flyAmp > 0)
return true;
return false;
}
public void setNumberOfActuators(int num) {
numberOfActuators = num;
}
public void setHoverAmp(double ampereHovering) {
this.hoverAmp = ampereHovering;
}
public void setFlyAmp(double ampereFlying) {
this.flyAmp = ampereFlying;
}
public void setVolt(double voltage) {
this.volt = voltage;
}
}
/*
* Copyright (c) 2005-2010 KOM � Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tud.kom.p2psim.impl.energy.configs;
import java.util.LinkedList;
import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.api.energy.EnergyConfiguration;
import de.tud.kom.p2psim.impl.energy.components.MotorCharacteristic;
import de.tud.kom.p2psim.impl.energy.components.StatelessActuatorComponent;
/**
*
*
* @author Julian Zobel
* @version 1.0, 05.03.2019
*/
public class StatelessActuatorConfiguration implements EnergyConfiguration<StatelessActuatorComponent> {
private int numberOfActuators;
private double volt;
private LinkedList<MotorCharacteristic> characteristics = new LinkedList<>();
@Override
public StatelessActuatorComponent getConfiguredEnergyComponent(SimHost host) {
StatelessActuatorComponent comp = new StatelessActuatorComponent(numberOfActuators, volt);
for (MotorCharacteristic c : characteristics) {
comp.addChar(c);
}
return comp;
}
@Override
public String getHelp() {
return "Fix actuator energy consumption config";
}
@Override
public boolean isWellConfigured() {
if(numberOfActuators >= 1 && volt > 0 && characteristics.size() >= 2) {
return true;
}
return false;
}
public void setNumberOfActuators(int num) {
numberOfActuators = num;
}
public void setVolt(double voltage) {
this.volt = voltage;
}
public void setMotorCharacteristic(MotorCharacteristic c) {
characteristics.add(c);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment