def __init__(self, id, xPos, yPos, frequencyBand, sendInterval, initialDelay): super(SendingDevice, self).__init__("Device" + str(id), xPos, yPos, frequencyBand) # initialize a physical layer only self._phy = SimplePhy("phy", self, frequencyBand) mcs = BpskMcs(frequencyBand) def sender(): yield SimMan.timeout(initialDelay) while True: yield SimMan.timeout(sendInterval) packet = Packet( SimpleMacHeader(bytes([0 for _ in range(5)] + [id % 255]), bytes([255 for _ in range(6)]), flag=0), Transmittable("A message to all my homies")) signal = Message(StackMessageTypes.SEND, { "packet": packet, "power": 40.0, "mcs": mcs }) self._phy.gates["macIn"].send(signal) SimMan.process(sender())
def __init__(self, name: str, frequencyBand: FrequencyBand, plant: SlidingPendulum): super(WagonActuator, self).__init__(name, plant.getWagonPos, 0, frequencyBand) self.plant = plant SimMan.process(self._positionUpdater())
def __init__(self, name): super(TestModule, self).__init__(name) self._addPort("a") self._addPort("b") self.msgReceivedCount = {"a": 0, "b": 0} self.msgVal = None SimMan.process(self.process("a", "b")) SimMan.process(self.process("b", "a"))
def __init__(self, name: str, xPos: float, yPos: float, frequencyBand: FrequencyBand, packetMultiplicity: int): super(CounterTrafficEnv.SenderDevice, self).__init__(name, xPos, yPos, frequencyBand) self.packetMultiplicity = packetMultiplicity self.counter = 1 SimMan.process(self.senderProcess()) self.destinationMac: bytes = None # to be set after construction
def __init__(self, name: str, frequencyBand: FrequencyBand, plant: SlidingPendulum, controllerAddr: bytes, sampleInterval: float): super(AngleSensor, self).__init__(name, plant.getWagonPos(), 0, frequencyBand) self.plant = plant self.controllerAddr = controllerAddr self.sampleInterval = sampleInterval SimMan.process(self._sensor())
def mobile_device_grid(device_grid): def mover(d: NetworkDevice): yield SimMan.timeout(random.uniform(0, MOVE_INTERVAL)) initialPos = d.position while True: xOffset = random.uniform(-.2, .2) yOffset = random.uniform(-.2, .2) d.position.set(initialPos.x + xOffset, initialPos.y + yOffset) yield SimMan.timeout(MOVE_INTERVAL) for device in device_grid: SimMan.process(mover(device))
def __init__(self, name: str, xPos: float, yPos: float, frequencyBand: FrequencyBand): super(InvertedPendulumPidController, self).__init__(name, xPos, yPos, frequencyBand) self._angle = 0 self.sensorAddr = None """bytes: The sensor's network address""" self.actuatorAddr = None """bytes: The actuator's network address""" SimMan.process(self.control)
def __init__(self, world: ode.World = None): """ Args: world: A py3ode :class:`World` object. If not provided, a new one will be created with gravity ``(0,-9.81,0)``. """ if world is None: world = ode.World() world.setGravity((0, -9.81, 0)) self.world = world self.maxStepSize = 0.05 self._lastUpdateSimTime = SimMan.now SimMan.process(self._stateUpdater())
def receiving(self, receiving: bool): if receiving != self._receiving: if receiving: # start receiving if self._receiverProcess is None: self._receiverProcess = SimMan.process(self._receiver()) self._receiving = receiving
def __init__(self, world: ode.World = None, visualized=False): super(SlidingPendulum, self).__init__(world) # Bodies and joints # Create wagon wagon = ode.Body(self.world) M = ode.Mass() M.setSphere(2500, 0.05) wagon.setMass(M) wagon.setPosition((0, 1, 0)) # Create pendulum pendulum = ode.Body(self.world) M = ode.Mass() M.setSphere(2500, 0.05) pendulum.setMass(M) pendulum.setPosition((0, 2, 0)) # Connect wagon with the static environment using a slider joint slider = ode.SliderJoint(self.world) slider.attach(ode.environment, wagon) slider.setAxis((1, 0, 0)) # Connect pendulum with wagon arm = ode.HingeJoint(self.world) arm.attach(wagon, pendulum) arm.setAnchor(wagon.getPosition()) arm.setAxis((0, 0, 1)) self._wagon = wagon self._pendulum = pendulum self._slider = slider self._arm = arm slider.setParam(ode.ParamVel, 0.1) slider.setParam(ode.ParamFMax, 22) # used to be 22 # visualization self._visualized = visualized if visualized: surface = pygame.display.set_mode((640, 480)) SimMan.process(self._screenUpdater(surface))
def test_gate_listener_generator(caplog): caplog.set_level(logging.DEBUG, logger='gymwipe.networking.construction') SimMan.init() # Checking side effects by using two identical modules again modules = MyModule("Test1"), MyModule("Test2") def main(): for i in range(3): for module in modules: module.gates["bIn"].send("msg" + str(i)) yield SimMan.timeout(1) SimMan.process(main()) SimMan.runSimulation(40) for module in modules: # Non-queued PortListener should only have received the first message, # since receiving takes 10 time units and the send interval is 1 time unit. assert module.logs[2] == ["msg0"] # Queued PortListener should have received all messages. assert module.logs[3] == ["msg" + str(n) for n in range(3)]
def test_notifier_simpy(caplog, simman): caplog.set_level(logging.DEBUG, logger='gymwipe.simtools') n = Notifier("notifier") p1, p2, p3 = [makeLoggingProcess(10) for _ in range(3)] n.subscribeProcess(p1, blocking=False) n.subscribeProcess(p2, blocking=True, queued=False) n.subscribeProcess(p3, blocking=True, queued=True) def main(): for i in range(1, 3): n.trigger("msg" + str(i)) yield SimMan.timeout(1) SimMan.process(main()) SimMan.runSimulation(4) # After 4 time units: # Two instances of p1 should be running assert p1.instanceCounter == 2 # and the last one should have been started with value "msg2". assert p1.value == "msg2" # One instance of each p2 and p3 should be running (others are blocked). assert p2.instanceCounter == 1 assert p2.value == "msg1" assert p3.instanceCounter == 1 assert p3.value == "msg1" SimMan.runSimulation(11) # After 15 time units: # All p1 instances should have finished. assert p1.instanceCounter == 0 # The first p2 instance should have finished and no other p2 instance should # be running. assert p2.instanceCounter == 0 assert p2.value == "msg1" # The second p3 instance should be the only p3 instance at that time. assert p3.instanceCounter == 1 assert p3.value == "msg2" # Triggering the notifier again, in order to proof that another instance of # p2 will start n.trigger("msg3") SimMan.runSimulation(1) # p2 should be running again, triggered by message 3 assert p2.instanceCounter == 1 assert p2.value == "msg3" SimMan.runSimulation(25) # In the end, all instances should have finished assert p1.instanceCounter == 0 assert p2.instanceCounter == 0 assert p3.instanceCounter == 0 # and they all should have processed message 3 at last assert p1.value == "msg3" assert p2.value == "msg3" assert p3.value == "msg3"
def test_simple_phy(caplog, mocker, simple_phy): caplog.set_level(logging.INFO, logger='gymwipe.networking.construction') caplog.set_level(logging.INFO, logger='gymwipe.networking.core') caplog.set_level(logging.DEBUG, logger='gymwipe.networking.physical') caplog.set_level(logging.INFO, logger='gymwipe.networking.simple_stack') caplog.set_level(logging.INFO, logger='gymwipe.simtools') setup = simple_phy frequencyBand = setup.frequencyBand senderPhy = setup.device1Phy receiverPhy = setup.device2Phy # create a mocked port for capturing receiver Phy output receiverCallbackMock = mocker.Mock() receiverPort = Port("Receiver Stack") receiverPort.input.nReceives.subscribeCallback(receiverCallbackMock) receiverPhy.gates["macOut"].connectTo(receiverPort.input) # create something transmittable packet = Packet(FakeTransmittable(8), FakeTransmittable(128)) def sending(): # the frequency band should be unused yet assert len(frequencyBand.getActiveTransmissions()) == 0 # setup the message to the physical layer MCS = BpskMcs(frequencyBand.spec) POWER = 0.0 # dBm cmd = Message(StackMessageTypes.SEND, { "packet": packet, "power": POWER, "mcs": MCS }) # send the message to the physical layer senderPhy.gates["macIn"].send(cmd) # wait 8 payload bits yield SimMan.timeout(8 / MCS.dataRate) # assertions for the transmission transmissions = frequencyBand.getActiveTransmissions() assert len(transmissions) == 1 t = transmissions[0] # check the correctness of the transmission created assert t.packet == packet assert t.power == POWER assert t.mcsHeader == MCS assert t.mcsPayload == MCS power = receiverPhy._receivedPower # wait another 64 bits yield SimMan.timeout(64 / MCS.dataRate) # move device 2 setup.device2.position.x = 2 yield SimMan.timeout(16 / MCS.dataRate) assert receiverPhy._receivedPower < power yield SimMan.timeout(1) assert len(frequencyBand.getActiveTransmissions()) == 0 def receiving(): yield SimMan.timeout(4) receiverCallbackMock.assert_called_with(packet) SimMan.process(sending()) SimMan.process(receiving()) SimMan.runSimulation(200)
def test_simple_mac(caplog, simple_mac): caplog.set_level(logging.INFO, logger='gymwipe.networking.construction') caplog.set_level(logging.INFO, logger='gymwipe.networking.core') caplog.set_level(logging.INFO, logger='gymwipe.networking.physical') caplog.set_level(logging.DEBUG, logger='gymwipe.networking.simple_stack') caplog.set_level(logging.INFO, logger='gymwipe.simtools') s = simple_mac dev1Addr = s.device1Mac.addr dev2Addr = s.device2Mac.addr def sender(fromMacLayer: SimpleMac, toMacLayer: SimpleMac, payloads: Iterable): # send a bunch of packets from `fromMacLayer` to `toMacLayer` for p in payloads: packet = Packet( SimpleNetworkHeader(fromMacLayer.addr, toMacLayer.addr), p) fromMacLayer.gates["networkIn"].send(packet) yield SimMan.timeout(1e-4) def receiver(macLayer: SimpleMac, receivedPacketsList: List[Packet]): # receive forever while True: receiveCmd = Message(StackMessageTypes.RECEIVE, {"duration": 10}) macLayer.gates["networkIn"].send(receiveCmd) result = yield receiveCmd.eProcessed if result is not None: receivedPacketsList.append(result) ASSIGN_TIME = 0.01 ANNOUNCE_TIME = (13 + log10(ASSIGN_TIME / TIME_SLOT_LENGTH) ) * 8 / s.rrmMac._announcementMcs.dataRate # 13 bytes header + log10(ASSIGN_TIME/TIME_SLOT_LENGTH) bytes payload def resourceManagement(): # Assign the frequency band 5 times for each device previousCmd = None for i in range(10): if i % 2 == 0: dest = dev1Addr else: dest = dev2Addr cmd = Message(StackMessageTypes.ASSIGN, { "duration": ASSIGN_TIME / TIME_SLOT_LENGTH, "dest": dest }) s.rrmMac.gates["networkIn"].send(cmd) if previousCmd is not None: yield previousCmd.eProcessed previousCmd = cmd receivedPackets1, receivedPackets2 = [], [] SimMan.process( sender(s.device1Mac, s.device2Mac, [Transmittable(i) for i in range(10)])) SimMan.process( sender(s.device2Mac, s.device1Mac, [Transmittable(i) for i in range(10, 20)])) SimMan.process(receiver(s.device1Mac, receivedPackets1)) SimMan.process(receiver(s.device2Mac, receivedPackets2)) SimMan.process(resourceManagement()) ROUND_TIME = ANNOUNCE_TIME + ASSIGN_TIME # After 1 assignment, device 2 should have received the first chunk of # packets. Highly depends on data rates, TIME_SLOT_LENGTH, and ASSIGN_TIME! SimMan.runSimulation(ROUND_TIME) assert len(receivedPackets2) == 4 SimMan.runSimulation(ROUND_TIME) # Same for device 1 assert len(receivedPackets1) == 4 SimMan.runSimulation(ROUND_TIME) assert len(receivedPackets2) == 8 SimMan.runSimulation(ROUND_TIME) assert len(receivedPackets1) == 8 SimMan.runSimulation(6 * ROUND_TIME) # Both devices should have received 10 packets assert len(receivedPackets1) == 10 assert len(receivedPackets2) == 10
def test_module_simulation(caplog, simman): # Connect two modules in a bidirectional cycle and let them pass around a message object in both directions # # <-----------------> # |----a-----| |----a-----| # | module 1 | | module 2 | # |----b-----| |----b-----| # <-----------------> caplog.set_level(logging.DEBUG, logger='gymwipe.networking.construction') class TestModule(Module): def __init__(self, name): super(TestModule, self).__init__(name) self._addPort("a") self._addPort("b") self.msgReceivedCount = {"a": 0, "b": 0} self.msgVal = None SimMan.process(self.process("a", "b")) SimMan.process(self.process("b", "a")) def process(self, fromPort: str, toPort: str): while (True): # Listen on port fromPort and proxy messages logger.info("Waiting for message", sender=fromPort) msg = yield self.ports[fromPort].nReceives.event self.msgVal = msg self.msgReceivedCount[fromPort] += 1 msg += 1 yield SimMan.env.timeout(1) # wait 1 time step before sending # change the direction every 10 times a message has been passed if msg % 10 == 0: self.ports[fromPort].output.send(msg) else: self.ports[toPort].output.send(msg) m1 = TestModule("1") m2 = TestModule("2") m1.ports["b"].biConnectWith(m2.ports["b"]) m2.ports["a"].biConnectWith(m1.ports["a"]) def simulation(): # send the test message (a zero) print("sending message") m1.gates["aIn"].send(1) # wait 40 time units yield SimMan.timeout(20) assert m1.msgVal == 19 assert m2.msgVal == 20 yield SimMan.timeout(20) # assertions for m in [m1, m2]: for portName in ["a", "b"]: assert m.msgReceivedCount[portName] == 10 SimMan.process(simulation()) SimMan.runSimulation(50)