public WirelessNetworkSimulation(WirelessNetwork baseNetwork, int?seed = null)
        {
            RandomSeed = seed == null?SeedingRandom.Next() : seed.Value;

            r = new Random(RandomSeed);

            Network = baseNetwork;

            foreach (var n in Network.Nodes)
            {
                Type t = Assembly.GetExecutingAssembly().GetType(n.NodeType);

                SimulatedNode simNode = (SimulatedNode)t.GetConstructor(new Type[] { }).Invoke(new object[] { });
                simNode.ParentSimulation = this;
                simNode.SourceNode       = n;
                simNode.MyID             = SimulationNodes.Count;

                WirelessSimulationNode sn = new WirelessSimulationNode()
                {
                    NetworkNode = n,
                    Node        = simNode
                };

                SimulationNodes.Add(sn);
            }
        }
Esempio n. 2
0
        public static WirelessUnitTests[] FindUnitTests()
        {
            List <WirelessUnitTests> outTests = new List <WirelessUnitTests>();

            Type[] nodeTypes = SimulatedNode.FindSimulatedNodeTypes();
            foreach (var node in nodeTypes)
            {
                List <WirelessUnitTest> tests = new List <WirelessUnitTest>();
                foreach (var method in node.GetMethods())
                {
                    WirelessUnitTestAttribute attribute = method.GetCustomAttribute <WirelessUnitTestAttribute>();
                    if (attribute != null)
                    {
                        // Todo: Verify that test is static, and accepts a single parameter taking WirelessUnitTestInstance.

                        tests.Add(new WirelessUnitTest()
                        {
                            UnitTestAttribute = attribute, UnitTestMethod = method, NodeType = node
                        });
                    }
                }
                if (tests.Count > 0)
                {
                    outTests.Add(new WirelessUnitTests()
                    {
                        NodeType = node, UnitTestMethods = tests.ToArray()
                    });
                }
            }
            return(outTests.ToArray());
        }
 public SimulationEvent(double start, SimulatedNode node, EventType t, object context = null, double end = double.MaxValue)
 {
     StartTime    = start;
     EndTime      = end;
     Origin       = node;
     Type         = t;
     EventContext = context;
 }
 public void SetButtonState(SimulatedNode n, bool state, int index = 0)
 {
     n.PastEvents.Append(new SimulationEvent(CurrentTime, n, EventType.ButtonChange, new ButtonEventContext()
     {
         Index = index, Pressed = state
     }));
     n.ButtonState[index] = state;
     ((ISimulatedDevice)n).InputEvent(index, state);
 }
        internal void NodeSetTimer(SimulatedNode n, double time, Action callback)
        {
            if (n.TimerEvent != null)
            {
                PendingEvents.Remove(n.TimerEvent);
                n.TimerEvent = null;
            }
            var context = new TimerEventContext()
            {
                Callback = callback, Time = time
            };

            n.PastEvents.Append(new SimulationEvent(CurrentTime, n, EventType.TimerSet, context));
            if (callback != null)
            {
                n.TimerEvent = new SimulationEvent(CurrentTime + time, n, EventType.TimerComplete, context);
                PendingEvents.Insert(n.TimerEvent);
            }
        }
        bool NodeIsReceiving(SimulatedNode n)
        {
            if (n.ReceiverCurrentContext is bool)
            {
                return((bool)n.ReceiverCurrentContext);
            }
            var context = n.ReceiverCurrentContext as ReceiverPollingContext;

            if (context != null)
            {
                double timeSinceEvent  = CurrentTime - n.ReceiverStateChangeTime;
                double pollCycleLength = context.TimeOn + context.TimeOff;

                // Find offset in receive cycle.
                double cycleOffset = timeSinceEvent - Math.Floor(timeSinceEvent / pollCycleLength) * pollCycleLength;

                // Does the offset in the polling cycle fall in the on time?
                return(cycleOffset < context.TimeOn);
            }
            throw new Exception("Invalid state for receiver context");
        }
Esempio n. 7
0
        public static WirelessReport[] FindReports()
        {
            List <WirelessReport> outReports = new List <WirelessReport>();

            Type[] nodeTypes = SimulatedNode.FindSimulatedNodeTypes();
            foreach (var node in nodeTypes)
            {
                foreach (var method in node.GetMethods())
                {
                    WirelessReportAttribute attribute = method.GetCustomAttribute <WirelessReportAttribute>();
                    if (attribute != null)
                    {
                        // Todo: Verify that test is static, and accepts a single parameter taking WirelessUnitTestInstance.

                        outReports.Add(new WirelessReport()
                        {
                            NodeType = node, ReportAttribute = attribute, ReportMethod = method
                        });
                    }
                }
            }
            return(outReports.ToArray());
        }
Esempio n. 8
0
        public SimulationEvent FindFirstNodeEvent(SimulatedNode node, double exclusiveStartTime, double inclusiveEndTime, Func <SimulationEvent, bool> filter = null)
        {
            foreach (var e in node.PastEvents.Events)
            {
                if (e.StartTime <= exclusiveStartTime)
                {
                    continue;
                }
                if (e.StartTime > inclusiveEndTime)
                {
                    break;
                }

                if (!filter(e))
                {
                    continue;
                }

                // Found an event that matches the criteria
                return(e);
            }
            return(null);
        }
        internal void NodeSendPacket(SimulatedNode n, object packet, double preDelay)
        {
            WirelessPacket wp = new WirelessPacket()
            {
                StartTime = CurrentTime + preDelay, Origin = n, PacketContents = packet
            };

            // Compute how long the packet is being transmitted for
            double transmitSpeed = 2000000;
            int    packetBits    = 18 * 8;

            double packetTime = packetBits / (transmitSpeed * n.DeviceTimingSkew);

            wp.EndTime = wp.StartTime + packetTime;

            n.PastEvents.Append(new SimulationEvent(CurrentTime, n, EventType.Packet, wp, end: wp.EndTime));

            // Find nodes that are in range
            foreach (var sn in SimulationNodes)
            {
                // For each node,
                // Determine whether the node is listening when the packet starts
                if (sn.Node == n)
                {
                    continue;               // Don't send to self.
                }
                // Future: deal with Z differences
                Vector v        = new Vector(sn.NetworkNode.X - n.SourceNode.X, sn.NetworkNode.Y - n.SourceNode.Y);
                double distance = v.Length;
                if (distance > Network.BaseTransmitRange)
                {
                    continue;                                      // Node out of range.
                }
                const double TransmitPropogationSpeed = 300000000; // Speed of RF propogation in air (Close enough)

                WirelessPacketTransmission t = new WirelessPacketTransmission()
                {
                    Packet         = wp,
                    Receiver       = sn.Node,
                    ReceiveSuccess = true,
                    SignalLevel    = 0,
                    WirelessDelay  = distance / TransmitPropogationSpeed
                };

                // Add a random spike noise check to occasionally drop the packet regardless of other factors.
                double randomNoiseChance = 0.01; // 1% of packets drop due to random environmental noise
                if (NextRandom() <= randomNoiseChance)
                {
                    t.ReceiveSuccess = false;
                }

                // Assign a "received signal level" to this packet, and check against a random noise floor (some packets will not be received due to environmental factors)
                // Signal level can be attenuated by walls in the future, and can be used for overlap checks.

                // for now, give signal level between 0 (distance 0) and -80 (distance full)
                t.SignalLevel = 0 - 80 * (distance / Network.BaseTransmitRange);

                // Seperately randomly drop packets based on distance.
                if (NextRandom() < (distance / Network.BaseTransmitRange) * 0.7)
                {
                    // 70% chance to fail receive at max range.
                    t.ReceiveSuccess = false;
                }

                // Check whether this packet transmit window overlaps other packets, if so drop both packets (for now)
                foreach (var otherPacket in sn.Node.InFlightPackets)
                {
                    if (t.Overlaps(otherPacket))
                    {
                        t.ReceiveSuccess           = false;
                        t.Collision                = true;
                        otherPacket.ReceiveSuccess = false;
                        otherPacket.Collision      = true;
                    }
                }

                // Check whether the target node is receiving at time of packet start
                // Note: this actually uses the current time (ignores air propogation time, which is negligible)
                if (!NodeIsReceiving(sn.Node))
                {
                    // Node is not receiving, would miss the packet.
                    t.ReceiveSuccess = false;
                }

                // Queue this pending packet (end transmission, and in node pending list)
                PendingEvents.Insert(new SimulationEvent(t.EndTime, sn.Node, EventType.PacketComplete, t));
                sn.Node.InFlightPackets.Add(t);
            }
        }
 internal void NodeSetLed(SimulatedNode n, Color c)
 {
     n.LedColor = c;
     n.PastEvents.Append(new SimulationEvent(CurrentTime, n, EventType.LedChange, c));
     LedStateChanged?.Invoke();
 }
 internal void NodeSetReceiverState(SimulatedNode n, object stateContext)
 {
     n.PastEvents.Append(new SimulationEvent(CurrentTime, n, EventType.PowerState, stateContext));
     n.ReceiverStateChangeTime = CurrentTime;
     n.ReceiverCurrentContext  = stateContext;
 }
Esempio n. 12
0
 public SimulationEvent FindFirstLedColor(SimulatedNode node, double exclusiveStartTime, double inclusiveEndTime, Func <Color, bool> filter = null)
 {
     return(FindFirstNodeEvent(node, exclusiveStartTime, inclusiveEndTime, (e) => e.Type == EventType.LedChange && (filter == null || filter((Color)e.EventContext))));
 }
Esempio n. 13
0
 public SimulationEvent FindFirstReceivedPacket(SimulatedNode node, double exclusiveStartTime, double inclusiveEndTime, Func <SimulationEvent, bool> filter = null)
 {
     // Note StartTime for PacketComplete event is the time the packet was received.
     return(FindFirstNodeEvent(node, exclusiveStartTime, inclusiveEndTime,
                               (e) => e.Type == EventType.PacketComplete && ((WirelessPacketTransmission)e.EventContext).ReceiveSuccess && (filter == null || filter(e))));
 }
Esempio n. 14
0
        void InitComboBox()
        {
            comboBox.Items.Clear();

            comboBox.Items.Add(new ComboBoxItem()
            {
                Content     = "Move",
                DataContext = new ActionContext()
                {
                    MouseMove = MoveMouseMove, MouseDown = MoveMouseDown, MouseUp = MoveMouseUp
                }
            });

            comboBox.Items.Add(new ComboBoxItem()
            {
                Content     = "Delete Node",
                DataContext = new ActionContext()
                {
                    MouseMove = MoveHighlightNode, MouseDown = DeleteMouseDown, MouseUp = DeleteMouseUp
                }
            });


            InteractItem = (new ComboBoxItem()
            {
                Content = "Interact with Node",
                DataContext = new ActionContext()
                {
                    MouseMove = MoveHighlightNode, MouseDown = InteractMouseDown, MouseUp = InteractMouseUp
                }
            });
            comboBox.Items.Add(InteractItem);

            comboBox.Items.Add(new Separator());

            // Add nodes
            ComboBoxItem firstItem = null;

            foreach (var type in SimulatedNode.FindSimulatedNodeTypes())
            {
                ComboBoxItem item = new ComboBoxItem()
                {
                    Content     = $"Add Node: {type.Name}",
                    DataContext = new ActionContext()
                    {
                        MouseMove = MoveHighlightNode, MouseDown = AddMouseDown, MouseUp = AddMouseUp, AddNodeType = type
                    }
                };
                if (firstItem == null)
                {
                    firstItem = item;
                }
                comboBox.Items.Add(item);
            }

            // If there is a node, select the first node.
            if (firstItem != null)
            {
                comboBox.SelectedItem = firstItem;
            }
        }
Esempio n. 15
0
 internal void BindNode(DebugTimeWindow timeline, SimulatedNode node)
 {
     Timeline = timeline;
     Node     = node;
     InvalidateVisual();
 }