-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
energy model #5
base: master
Are you sure you want to change the base?
energy model #5
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
class EnergyModel: | ||
"""base class for energy models""" | ||
def __init__(self, max_energy: float, idle: float, receive: float, forward: float, name: str): | ||
""" | ||
@param max_energy: max energy of the model | ||
@param idle: amount of energy the model consumes in idle | ||
@param receive: amount of energy the model consumes upon message receival | ||
@param forward: amount of energy the model consumes upon forward of message | ||
""" | ||
self.max_energy: float = max_energy | ||
self._idle: float = idle | ||
self._receive: float = receive | ||
self._forward: float = forward | ||
self._name: str = name | ||
self.energy: float = max_energy | ||
|
||
def __str__(self) -> str: | ||
return self._name | ||
|
||
def __repr__(self) -> str: | ||
return str(self) | ||
|
||
def on_receive(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the function name should match the one in node.py from where it is called, e.g., on_recv |
||
"""handling message receive""" | ||
self.energy -= self._receive | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where is the transmission time? sending costs a specific amount of energy per time. so a large chunk of data might need several minutes and thus should consume more power |
||
|
||
def on_forward(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the function name should match the one in node.py from where it is called, e.g., on_send |
||
"""handling message forward""" | ||
self.energy -= self._forward | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where is the transmission time? sending costs a specific amount of energy per time. so a large chunk of data might need several minutes and thus should consume more power |
||
|
||
def on_idle(self, interval: float = 1.0): | ||
"""handling idle""" | ||
self.energy -= self._idle * interval | ||
|
||
|
||
class DefaultEnergyModel(EnergyModel): | ||
"""unlimited energy model - equivalent to no energy model""" | ||
def __init__(self): | ||
super().__init__(100, 0, 0, 0, "DefaultEnergyModel") | ||
|
||
|
||
class ESP32Wifi(EnergyModel): | ||
"""energy model simulating the esp32 using wifi""" | ||
def __init__(self, initial_energy: int = 100000): | ||
super().__init__(initial_energy, 90, 100, 190, "ESP32 Wifi") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
from __future__ import annotations | ||
|
||
import math | ||
from copy import deepcopy | ||
import pons | ||
import random | ||
|
||
from copy import deepcopy | ||
from typing import TYPE_CHECKING | ||
|
||
import pons | ||
|
||
if TYPE_CHECKING: | ||
import pons.routing | ||
|
||
|
@@ -71,7 +70,7 @@ class Node(object): | |
"""A The ONE movement scenario. | ||
""" | ||
|
||
def __init__(self, node_id: int, net: List[NetworkSettings] = None, router: pons.routing.Router = None): | ||
def __init__(self, node_id: int, net: List[NetworkSettings] = None, router: pons.routing.Router = None, energy_model: pons.EnergyModel = None): | ||
self.id = node_id | ||
self.x = 0.0 | ||
self.y = 0.0 | ||
|
@@ -80,6 +79,9 @@ def __init__(self, node_id: int, net: List[NetworkSettings] = None, router: pons | |
for n in net: | ||
self.net[n.name] = deepcopy(n) | ||
self.router = router | ||
self.energy_model = energy_model | ||
if self.energy_model is None: | ||
self.energy_model = pons.DefaultEnergyModel() | ||
self.neighbors = {} | ||
for net in self.net.values(): | ||
self.neighbors[net.name] = [] | ||
|
@@ -112,13 +114,15 @@ def send(self, netsim: pons.NetSim, to_nid: int, msg: Message): | |
for nid in self.neighbors[net.name]: | ||
receiver = netsim.nodes[nid] | ||
netsim.net_stats["tx"] += 1 | ||
self.energy_model.on_forward() | ||
pons.delayed_execution(netsim.env, tx_time, | ||
receiver.on_recv(netsim, self.id, msg)) | ||
else: | ||
if to_nid in self.neighbors[net.name]: | ||
# self.log("sending msg %s to %d" % (msg, to_nid)) | ||
receiver = netsim.nodes[to_nid] | ||
netsim.net_stats["tx"] += 1 | ||
self.energy_model.on_forward() | ||
pons.delayed_execution(netsim.env, tx_time, | ||
receiver.on_recv(netsim, self.id, msg)) | ||
else: | ||
|
@@ -136,6 +140,7 @@ def on_recv(self, netsim: pons.NetSim, from_nid: int, msg: Message): | |
if from_nid in self.neighbors[net.name]: | ||
# print("Node %d received msg %s from %d" % (to_nid, msg, from_nid)) | ||
netsim.net_stats["rx"] += 1 | ||
self.energy_model.on_receive() | ||
if self.router is not None: | ||
if msg.id == "HELLO": | ||
self.router.on_scan_received(deepcopy(msg), from_nid) | ||
|
@@ -147,11 +152,33 @@ def on_recv(self, netsim: pons.NetSim, from_nid: int, msg: Message): | |
netsim.net_stats["drop"] += 1 | ||
|
||
|
||
def generate_nodes(num_nodes: int, offset: int = 0, net: List[NetworkSettings] = None, router: pons.routing.Router = None): | ||
def generate_nodes( | ||
num_nodes: int, | ||
offset: int = 0, | ||
net: List[NetworkSettings] = None, | ||
router: pons.routing.Router = None, | ||
energy_model: pons.EnergyModel or List[pons.EnergyModel] = None | ||
): | ||
""" | ||
generates nodes | ||
@param num_nodes: number of nodes | ||
@param offset: offset for the node ids | ||
@param net: a list of network settings | ||
@param router: the router to use (optional) | ||
@param energy_model: the energy model(s) (optional) - | ||
Either one energy model or a list of models matching num_nodes. | ||
If only one is given, it is used for every nodes. | ||
""" | ||
nodes = [] | ||
if net == None: | ||
if net is None: | ||
net = [] | ||
if energy_model is None: | ||
energy_model = pons.DefaultEnergyModel() | ||
if isinstance(energy_model, pons.EnergyModel): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe some errorhandling here would be nice with user feedback |
||
energy_model = [deepcopy(energy_model) for i in range(0, num_nodes)] | ||
if len(energy_model) != num_nodes: | ||
raise ValueError("size of energy_model should match num_nodes") | ||
for i in range(num_nodes): | ||
nodes.append(Node(i + offset, net=deepcopy(net), | ||
router=deepcopy(router))) | ||
router=deepcopy(router), energy_model=energy_model[i])) | ||
return nodes |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
from .router import Router | ||
import pons | ||
|
||
|
||
class DirectDeliveryRouter(Router): | ||
|
@@ -28,21 +29,20 @@ def on_peer_discovered(self, peer_id): | |
for msg in self.store: | ||
self.forward(msg) | ||
|
||
def on_msg_received(self, msg, remote_id): | ||
# self.log("msg received: %s from %d" % (msg, remote_id)) | ||
def on_msg_received(self, msg: pons.Message, remote_id: int): | ||
self.netsim.routing_stats['relayed'] += 1 | ||
if not self.is_msg_known(msg): | ||
self.remember(remote_id, msg) | ||
msg.hops += 1 | ||
self.store_add(msg) | ||
if msg.dst == self.my_id: | ||
# self.log("msg arrived", self.my_id) | ||
# print("msg arrived", self.my_id) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why did you replace the central logging with a print statement? |
||
self.netsim.routing_stats['delivered'] += 1 | ||
self.netsim.routing_stats['hops'] += msg.hops | ||
self.netsim.routing_stats['latency'] += self.env.now - msg.created | ||
else: | ||
# self.log("msg not arrived yet", self.my_id) | ||
# print("msg not arrived yet", self.my_id) | ||
self.forward(msg) | ||
else: | ||
# self.log("msg already known", self.history) | ||
# print("msg already known", self.history) | ||
self.netsim.routing_stats['dups'] += 1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
|
||
from copy import copy | ||
import pons | ||
|
||
HELLO_MSG_SIZE = 42 | ||
|
@@ -68,7 +66,8 @@ def start(self, netsim: pons.NetSim, my_id: int): | |
self.env.process(self.scan()) | ||
|
||
def scan(self): | ||
while True: | ||
node = self.netsim.nodes[self.my_id] | ||
while node.energy_model.energy > 0: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why have this check here? isn't it enough to have an energy check in the send and receive functions of node.py so the router or any other upper layers are not relevant any more? ofc the scan loop can also contain the check to avoid some CPU cycles but deactivating the node functions is the safe bet to ensure that no further communication happens |
||
# print("[%s] scanning..." % self.my_id) | ||
|
||
# assume some kind of peer discovery mechanism | ||
|
@@ -88,14 +87,16 @@ def scan(self): | |
yield self.env.timeout(self.scan_interval) | ||
|
||
def on_scan_received(self, msg: pons.Message, remote_id: int): | ||
if self.netsim.nodes[self.my_id].energy_model.energy <= 0: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why have this check here? isn't it enough to have an energy check in the send and receive functions of node.py so the router or any other upper layers are not relevant any more? ofc the scan loop can also contain the check to avoid some CPU cycles but deactivating the node functions is the safe bet to ensure that no further communication happens |
||
return | ||
# self.log("[%s] scan received: %s from %d" % | ||
# (self.my_id, msg, remote_id)) | ||
if msg.id == "HELLO" and remote_id not in self.peers: | ||
self.peers.append(remote_id) | ||
# self.log("NEW PEER: %d" % remote_id) | ||
self.on_peer_discovered(remote_id) | ||
# elif remote_id in self.peers: | ||
# self.log("DUP PEER: %d" % remote_id) | ||
# self.log("DUP PEER: %d" % remote_id) | ||
|
||
def on_peer_discovered(self, peer_id): | ||
self.log("peer discovered: %d" % peer_id) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be sending or tx