vlcSim 0.3.3__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vlcSim
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Python Package of Event-Oriented Simulation for visible light communication
5
5
  Home-page: https://gitlab.com/DaniloBorquez/simvlc/
6
6
  Author: Danilo Bórquez-Paredes
@@ -10,7 +10,7 @@ long_description = (this_directory / "README.md").read_text()
10
10
 
11
11
  setup(
12
12
  name="vlcSim",
13
- version="0.3.3",
13
+ version="0.3.4",
14
14
  license="MIT",
15
15
  description="Python Package of Event-Oriented Simulation for visible light communication",
16
16
  author="Danilo Bórquez-Paredes",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vlcSim
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Python Package of Event-Oriented Simulation for visible light communication
5
5
  Home-page: https://gitlab.com/DaniloBorquez/simvlc/
6
6
  Author: Danilo Bórquez-Paredes
@@ -2,6 +2,7 @@
2
2
  The :mod:`vlcsim.controller` module is in charge of managing the connections and the physical sustrate.
3
3
  """
4
4
 
5
+ from __future__ import annotations
5
6
  from .scene import *
6
7
  from enum import Enum
7
8
  import math
@@ -321,8 +322,7 @@ class Controller:
321
322
  if self.__allocationStatus == Controller.status.ALLOCATED:
322
323
  index = self.APPosition(connection.AP)
323
324
  self.__numberActiveConnections[index] += 1
324
- actualSlice = connection.nextSliceInAPWhenArriving(
325
- connection.AP) - 1
325
+ actualSlice = connection.nextSliceInAPWhenArriving(connection.AP) - 1
326
326
  actualTime = (
327
327
  (time // (connection.AP.slicesInFrame * connection.AP.sliceTime))
328
328
  * connection.AP.slicesInFrame
@@ -535,3 +535,101 @@ class Controller:
535
535
  :return: A list of lists containing the frames and slices of this AP
536
536
  """
537
537
  return self.__activeConnections[self.APPosition(ap)]
538
+
539
+ def default_alloc(
540
+ receiver, connection: Connection, scenario: Scenario, controller: Controller
541
+ ):
542
+ vleds = scenario.vleds
543
+ rfs = scenario.rfs
544
+ vled_snr = []
545
+ rf_snr = []
546
+ for vled in vleds:
547
+ vled_snr.append(scenario.snrVled(receiver, vled))
548
+ for rf in rfs:
549
+ rf_snr.append(scenario.snrRf(receiver, rf))
550
+
551
+ numberOfSlices = 0
552
+ for vled_pos in range(len(vleds)):
553
+ number_better_rf = 0
554
+ for rf_pos in range(len(rfs)):
555
+ if vled_snr[vled_pos] > rf_snr[rf_pos]:
556
+ if controller.numberOfActiveConnections(vleds[vled_pos]) < 5:
557
+ connection.AP = vleds[vled_pos]
558
+ connection.receiver.capacityFromAP = scenario.capacityVled(
559
+ receiver, connection.AP
560
+ )
561
+ numberOfSlices = connection.numberOfSlicesNeeded(
562
+ connection.capacityRequired,
563
+ connection.receiver.capacityFromAP,
564
+ )
565
+ connection.snr = vled_snr[vled_pos]
566
+ if numberOfSlices < 5:
567
+ number_better_rf += 1
568
+ break
569
+ else:
570
+ number_better_rf += 1
571
+ break
572
+ else:
573
+ number_better_rf += 1
574
+ break
575
+ if number_better_rf == 0:
576
+ break
577
+ if number_better_rf != 0:
578
+ best_rf_SNR = sys.float_info.min
579
+ best_rf = None
580
+ for rf_pos in range(len(rfs)):
581
+ if rf_snr[rf_pos] > best_rf_SNR:
582
+ best_rf_SNR = rf_snr[rf_pos]
583
+ best_rf = rf_pos
584
+ connection.AP = rfs[best_rf]
585
+ connection.receiver.capacityFromAP = scenario.capacityRf(
586
+ receiver, connection.AP
587
+ )
588
+ numberOfSlices = connection.numberOfSlicesNeeded(
589
+ connection.capacityRequired, connection.receiver.capacityFromAP
590
+ )
591
+ connection.snr = rf_snr[rf_pos]
592
+ else:
593
+ for vled_pos in range(len(vleds)):
594
+ if vled_snr[vled_pos] > connection.snr:
595
+ connection.AP = vleds[vled_pos]
596
+ connection.receiver.capacityFromAP = scenario.capacityVled(
597
+ receiver, connection.AP
598
+ )
599
+ numberOfSlices = connection.numberOfSlicesNeeded(
600
+ connection.capacityRequired, connection.receiver.capacityFromAP
601
+ )
602
+ connection.snr = vled_snr[vled_pos]
603
+
604
+ actualSlice = connection.nextSliceInAPWhenArriving(connection.AP)
605
+ aux = 0
606
+ auxFrame = 0
607
+
608
+ # Actual frame
609
+ for slice in range(actualSlice, connection.AP.slicesInFrame):
610
+ if (
611
+ len(controller.framesState(connection.AP)) == 0
612
+ or controller.framesState(connection.AP)[0][slice] == False
613
+ ):
614
+ connection.assignFrameSlice(0, slice)
615
+ aux += 1
616
+ break
617
+
618
+ # next frames
619
+ for frameIndex in range(1, len(controller.framesState(connection.AP))):
620
+ for slice in range(connection.AP.slicesInFrame):
621
+ if controller.framesState(connection.AP)[frameIndex][slice] == False:
622
+ connection.assignFrameSlice(frameIndex, slice)
623
+ aux += 1
624
+ auxFrame = frameIndex
625
+ break
626
+
627
+ if aux == numberOfSlices:
628
+ break
629
+
630
+ frameIndex = auxFrame + 1
631
+ while aux < numberOfSlices:
632
+ connection.assignFrameSlice(frameIndex, 0)
633
+ frameIndex += 1
634
+ aux += 1
635
+ return Controller.status.ALLOCATED, connection
@@ -467,6 +467,17 @@ class RF(AccessPoint):
467
467
 
468
468
  @property
469
469
  def pif(self) -> float:
470
+ """
471
+ The received SNR discrepancy from the continuous input memoryless channel’s capacity at the target BER. (pif=-1.5log2-1(5 BERf))
472
+
473
+ .. math::
474
+ \\begin{eqnarray}
475
+ pif = -1.5 \log_2^{-1}(5\cdot BERf)
476
+ \\end{eqnarray}
477
+
478
+ :return: SNR discrepancy
479
+ :rtype: float
480
+ """
470
481
  return self.__pif
471
482
 
472
483
  @pif.setter
@@ -489,6 +500,12 @@ class RF(AccessPoint):
489
500
 
490
501
  @property
491
502
  def nFactor_rf(self) -> float:
503
+ """
504
+ RF constant
505
+
506
+ :return: RF constant
507
+ :rtype: float
508
+ """
492
509
  return self.__nFactor_rf
493
510
 
494
511
  @nFactor_rf.setter
@@ -497,6 +514,12 @@ class RF(AccessPoint):
497
514
 
498
515
  @property
499
516
  def A(self) -> float:
517
+ """
518
+ Rayleigh distributed channel gain.
519
+
520
+ :return: Rayleigh distributed channel gain.
521
+ :rtype: float
522
+ """
500
523
  return self.__A
501
524
 
502
525
  @A.setter
@@ -505,7 +528,14 @@ class RF(AccessPoint):
505
528
 
506
529
 
507
530
  class Receiver:
531
+ """
532
+ Class that represents a VLC object
533
+ """
534
+
508
535
  receiversCreated = 0
536
+ """
537
+ Number of receivers created by this class.
538
+ """
509
539
 
510
540
  def __init__(
511
541
  self,
@@ -549,7 +579,7 @@ class Receiver:
549
579
  :type fov: float
550
580
  :param q: electronic load. Default is -1.602e-19 culombios
551
581
  :type q: float
552
- :param s: ibg b - parameter of the Ib - Galactic model. Default i 5 seconds.
582
+ :param s: ibg b - parameter of the Ib - Galactic model. Default is 5 seconds.
553
583
  :type s: float
554
584
  :param b: c b - parameter of the Ib - Galactic model. Default is 5 seconds.
555
585
  :type b: float
@@ -678,6 +708,12 @@ class Receiver:
678
708
 
679
709
  @property
680
710
  def aDet(self) -> float:
711
+ """
712
+ aDet value of the object's coordinate.
713
+
714
+ :return: aDet value of the object's coordinate.
715
+ :rtype: float
716
+ """
681
717
  return self.__aDet
682
718
 
683
719
  @aDet.setter
@@ -686,6 +722,12 @@ class Receiver:
686
722
 
687
723
  @property
688
724
  def ts(self) -> float:
725
+ """
726
+ time of the object's coordinate. Default is 10 seconds.
727
+
728
+ :return: time of the object's coordinate.
729
+ :rtype: float
730
+ """
689
731
  return self.__ts
690
732
 
691
733
  @ts.setter
@@ -694,6 +736,12 @@ class Receiver:
694
736
 
695
737
  @property
696
738
  def index(self) -> float:
739
+ """
740
+ order of Lambertian emission that depends on the half-angle at half illumination of the LED.
741
+
742
+ :return: order of Lambertian emission
743
+ :rtype: float
744
+ """
697
745
  return self.__index
698
746
 
699
747
  @index.setter
@@ -702,6 +750,12 @@ class Receiver:
702
750
 
703
751
  @property
704
752
  def fov(self) -> float:
753
+ """
754
+ width of the field of view.
755
+
756
+ :return: width of the field of view.
757
+ :rtype: float
758
+ """
705
759
  return self.__fov
706
760
 
707
761
  @fov.setter
@@ -713,7 +767,7 @@ class Receiver:
713
767
  return self.__gCon
714
768
 
715
769
  @property
716
- def position(self):
770
+ def position(self) -> float:
717
771
  """
718
772
  Return the position of the object. This is a tuple of ( x y z)
719
773
 
@@ -724,6 +778,12 @@ class Receiver:
724
778
 
725
779
  @property
726
780
  def q(self):
781
+ """
782
+ electronic load. Default is -1.602e-19 culombios
783
+
784
+ :return: electronic load.
785
+ :rtype: _type_
786
+ """
727
787
  return self.__q
728
788
 
729
789
  @q.setter
@@ -732,6 +792,11 @@ class Receiver:
732
792
 
733
793
  @property
734
794
  def s(self):
795
+ """
796
+ ibg b - parameter of the Ib - Galactic model. Default is 5 seconds.
797
+
798
+ :return: ibg b - parameter of the Ib - Galactic model.
799
+ """
735
800
  return self.__s
736
801
 
737
802
  @s.setter
@@ -740,6 +805,11 @@ class Receiver:
740
805
 
741
806
  @property
742
807
  def b(self):
808
+ """
809
+ c b - parameter of the Ib - Galactic model.
810
+
811
+ :return: c b - parameter of the Ib - Galactic model.
812
+ """
743
813
  return self.__b
744
814
 
745
815
  @b.setter
@@ -747,7 +817,13 @@ class Receiver:
747
817
  self.__b = value
748
818
 
749
819
  @property
750
- def ibg(self):
820
+ def ibg(self) -> float:
821
+ """
822
+ background current. Default is 5.1e-3 Amperes.
823
+
824
+ :return: background current.
825
+ :rtype: float
826
+ """
751
827
  return self.__ibg
752
828
 
753
829
  @ibg.setter
@@ -755,7 +831,13 @@ class Receiver:
755
831
  self.__ibg = value
756
832
 
757
833
  @property
758
- def cb(self):
834
+ def cb(self) -> float:
835
+ """
836
+ Boltzmann constant. Default is 1.380649e-23 J/K.
837
+
838
+ :return: Boltzmann constant.
839
+ :rtype: float
840
+ """
759
841
  return self.__cb
760
842
 
761
843
  @cb.setter
@@ -763,7 +845,7 @@ class Receiver:
763
845
  self.__cb = value
764
846
 
765
847
  @property
766
- def tk(self):
848
+ def tk(self) -> float:
767
849
  return self.__tk
768
850
 
769
851
  @tk.setter
@@ -771,7 +853,13 @@ class Receiver:
771
853
  self.__tk = value
772
854
 
773
855
  @property
774
- def a(self):
856
+ def a(self) -> float:
857
+ """
858
+ n n - parameter of the B - parameter. Default is 10 seconds.
859
+
860
+ :return: n n - B - parameter
861
+ :rtype: float
862
+ """
775
863
  return self.__a
776
864
 
777
865
  @a.setter
@@ -779,7 +867,13 @@ class Receiver:
779
867
  self.__a = value
780
868
 
781
869
  @property
782
- def gv(self):
870
+ def gv(self) -> float:
871
+ """
872
+ Open-loop voltage gain. Default is 10
873
+
874
+ :return: Open-loop voltage gain.
875
+ :rtype: float
876
+ """
783
877
  return self.__gv
784
878
 
785
879
  @gv.setter
@@ -787,7 +881,13 @@ class Receiver:
787
881
  self.__gv = value
788
882
 
789
883
  @property
790
- def n(self):
884
+ def n(self) -> float:
885
+ """
886
+ Fixed capacitance of the PD per unit area. Default is 1.12e-6.
887
+
888
+ :return: Fixed capacitance of the PD per unit area.
889
+ :rtype: float
890
+ """
791
891
  return self.__n
792
892
 
793
893
  @n.setter
@@ -795,7 +895,13 @@ class Receiver:
795
895
  self.__n = value
796
896
 
797
897
  @property
798
- def fr(self):
898
+ def fr(self) -> float:
899
+ """
900
+ FET channel noise factor. Default is 1.5
901
+
902
+ :return: FET channel noise factor.
903
+ :rtype: float
904
+ """
799
905
  return self.__fr
800
906
 
801
907
  @fr.setter
@@ -803,7 +909,13 @@ class Receiver:
803
909
  self.__fr = value
804
910
 
805
911
  @property
806
- def gm(self):
912
+ def gm(self) -> float:
913
+ """
914
+ FET transconductance. Default is 3e-2.
915
+
916
+ :return: FET transconductance.
917
+ :rtype: float
918
+ """
807
919
  return self.__gm
808
920
 
809
921
  @gm.setter
@@ -811,7 +923,13 @@ class Receiver:
811
923
  self.__gm = value
812
924
 
813
925
  @property
814
- def i1(self):
926
+ def i1(self) -> float:
927
+ """
928
+ constant experimental value. Default is 0.562.
929
+
930
+ :return: constant experimental value.
931
+ :rtype: float
932
+ """
815
933
  return self.__i1
816
934
 
817
935
  @i1.setter
@@ -819,7 +937,13 @@ class Receiver:
819
937
  self.__i1 = value
820
938
 
821
939
  @property
822
- def i2(self):
940
+ def i2(self) -> float:
941
+ """
942
+ constant experimental value. Default is 0.0868.
943
+
944
+ :return: constant experimental value.
945
+ :rtype: float
946
+ """
823
947
  return self.__i2
824
948
 
825
949
  @i2.setter
@@ -827,7 +951,13 @@ class Receiver:
827
951
  self.__i2 = value
828
952
 
829
953
  @property
830
- def timeFirstConnected(self):
954
+ def timeFirstConnected(self) -> float:
955
+ """
956
+ time point at which this receiver was first connected
957
+
958
+ :return: time point at which this receiver was first connected
959
+ :rtype: float
960
+ """
831
961
  return self.__timeFirstConnected
832
962
 
833
963
  @timeFirstConnected.setter
@@ -835,7 +965,13 @@ class Receiver:
835
965
  self.__timeFirstConnected = value
836
966
 
837
967
  @property
838
- def goalTime(self):
968
+ def goalTime(self) -> float:
969
+ """
970
+ Amount of time that this receiver will be connected. Depends on tha SNR.
971
+
972
+ :return: Amount of time that this receiver will be connected.
973
+ :rtype: float
974
+ """
839
975
  return self.__goalTime
840
976
 
841
977
  @goalTime.setter
@@ -843,7 +979,13 @@ class Receiver:
843
979
  self.__goalTime = value
844
980
 
845
981
  @property
846
- def timeActive(self):
982
+ def timeActive(self) -> float:
983
+ """
984
+ Effective time connected.
985
+
986
+ :return: Effective time connected
987
+ :rtype: float
988
+ """
847
989
  return self.__timeActive
848
990
 
849
991
  @timeActive.setter
@@ -851,7 +993,13 @@ class Receiver:
851
993
  self.__timeActive = value
852
994
 
853
995
  @property
854
- def timeFinished(self):
996
+ def timeFinished(self) -> float:
997
+ """
998
+ point in time when this receiver wil be finished.
999
+
1000
+ :return: point in time when this receiver wil be finished.
1001
+ :rtype: float
1002
+ """
855
1003
  return self.__timeFinished
856
1004
 
857
1005
  @timeFinished.setter
@@ -860,7 +1008,21 @@ class Receiver:
860
1008
 
861
1009
 
862
1010
  class Scenario:
1011
+ """
1012
+ Class that represents the characteristics of the scenario
1013
+
1014
+ :return: _description_
1015
+ :rtype: _type_
1016
+ """
1017
+
863
1018
  numberOfAPs = 0
1019
+ """
1020
+ Number of access points in the scenario.
1021
+
1022
+ :return: Number of access points in the scenario.
1023
+ :rtype: int
1024
+ """
1025
+
864
1026
  warnings.filterwarnings(
865
1027
  "ignore", message="invalid value encountered in double_scalars"
866
1028
  )
@@ -868,6 +1030,19 @@ class Scenario:
868
1030
  def __init__(
869
1031
  self, width: float, length: float, height: float, nGrids: int, rho: float
870
1032
  ) -> None:
1033
+ """Scenario Constructor
1034
+
1035
+ :param width: Width of the room
1036
+ :type width: float
1037
+ :param length: Length of the room
1038
+ :type length: float
1039
+ :param height: Height of the room
1040
+ :type height: float
1041
+ :param nGrids: Number of grids of each VLED
1042
+ :type nGrids: int
1043
+ :param rho: Reflexion coefficient
1044
+ :type rho: float
1045
+ """
871
1046
  self.__length = length # x
872
1047
  self.__width = width # y
873
1048
  self.__height = height # z
@@ -897,16 +1072,38 @@ class Scenario:
897
1072
  self.__g_xyz = np.array([self.__g_x, self.__g_y, self.__g_z], dtype=object)
898
1073
 
899
1074
  def addVLed(self, vled: VLed):
1075
+ """
1076
+ Add a VLED to this Scenario
1077
+
1078
+ :param vled: the VLED to be added
1079
+ :type vled: VLed
1080
+ """
900
1081
  self.__vleds.append(vled)
901
1082
  self.__vledsPositions.append(Scenario.numberOfAPs)
902
1083
  Scenario.numberOfAPs += 1
903
1084
 
904
1085
  def addRF(self, rf: RF):
1086
+ """
1087
+ Add an RF to this Scenario
1088
+
1089
+ :param rf: The RF to be added
1090
+ :type rf: RF
1091
+ """
905
1092
  self.__femtocells.append(rf)
906
1093
  self.__rfsPositions.append(Scenario.numberOfAPs)
907
1094
  Scenario.numberOfAPs += 1
908
1095
 
909
1096
  def getPowerInPointFromWalls(self, receiver: Receiver, vledID: int) -> float:
1097
+ """
1098
+ Get the incident power in an specific point in the room, received from the walls.
1099
+
1100
+ :param receiver: The receiver which is in the point
1101
+ :type receiver: Receiver
1102
+ :param vledID: The VLED that is sending the signal
1103
+ :type vledID: int
1104
+ :return: Power from walls
1105
+ :rtype: float
1106
+ """
910
1107
  vled = self.__vleds[vledID]
911
1108
  h1 = self.__channelGainWall(receiver, vled, 1, 0)
912
1109
  h2 = self.__channelGainWall(receiver, vled, 0, 1)
@@ -916,6 +1113,16 @@ class Scenario:
916
1113
  return float(power)
917
1114
 
918
1115
  def getPowerInPointFromVled(self, receiver: Receiver, vledID: int) -> float:
1116
+ """
1117
+ Get the power from the VLED in LOS
1118
+
1119
+ :param receiver: The receiver which is in the point
1120
+ :type receiver: Receiver
1121
+ :param vledID: The VLED that is sending the signal
1122
+ :type vledID: int
1123
+ :return: Power from VLED
1124
+ :rtype: float
1125
+ """
919
1126
  vled = self.__vleds[vledID]
920
1127
  D_los = m.sqrt(
921
1128
  (receiver.x - vled.x) ** 2
@@ -940,7 +1147,23 @@ class Scenario:
940
1147
  )
941
1148
  return power
942
1149
 
943
- def __channelGainWall(self, receiver: Receiver, vled, posVar, posFixed) -> float:
1150
+ def __channelGainWall(
1151
+ self, receiver: Receiver, vled: VLed, posVar: int, posFixed: int
1152
+ ) -> float:
1153
+ """
1154
+ Gain in channel from walls
1155
+
1156
+ :param receiver: The receiver which is in the point
1157
+ :type receiver: Receiver
1158
+ :param vled: The VLED that is sending the signal
1159
+ :type vled: VLed
1160
+ :param posVar: Auxiliar variable
1161
+ :type posVar: int
1162
+ :param posFixed: Auxiliar variable
1163
+ :type posFixed: int
1164
+ :return: Gain in channel
1165
+ :rtype: float
1166
+ """
944
1167
  wall = None
945
1168
  dA = self.__height
946
1169
  if posFixed == 0:
@@ -978,23 +1201,53 @@ class Scenario:
978
1201
  return h
979
1202
 
980
1203
  @property
981
- def numberOfVLeds(self):
1204
+ def numberOfVLeds(self) -> int:
1205
+ """
1206
+ number of VLeds in this scenario
1207
+
1208
+ :return: number of vleds
1209
+ :rtype: int
1210
+ """
982
1211
  return len(self.__vleds)
983
1212
 
984
1213
  @property
985
- def numberOfRFs(self):
1214
+ def numberOfRFs(self) -> int:
1215
+ """
1216
+ Number of RFs in this scenario
1217
+
1218
+ :return: number of RFs
1219
+ :rtype: int
1220
+ """
986
1221
  return len(self.__femtocells)
987
1222
 
988
1223
  @property
989
- def vleds(self):
1224
+ def vleds(self) -> list:
1225
+ """
1226
+ set of VLEDs in this scenario.
1227
+
1228
+ :return: set of VLEDs
1229
+ :rtype: list
1230
+ """
990
1231
  return self.__vleds
991
1232
 
992
1233
  @property
993
- def rfs(self):
1234
+ def rfs(self) -> list:
1235
+ """
1236
+ List of RFs in this scenario
1237
+
1238
+ :return: List of RFs
1239
+ :rtype: list
1240
+ """
994
1241
  return self.__femtocells
995
1242
 
996
1243
  @property
997
- def start_x(self):
1244
+ def start_x(self) -> float:
1245
+ """
1246
+ Auxiliar variable determining the starting X coordinate of the room
1247
+
1248
+ :return: Starting X coordinate
1249
+ :rtype: float
1250
+ """
998
1251
  return self.__start_x
999
1252
 
1000
1253
  @start_x.setter
@@ -1002,7 +1255,13 @@ class Scenario:
1002
1255
  self.__start_x = value
1003
1256
 
1004
1257
  @property
1005
- def start_y(self):
1258
+ def start_y(self) -> float:
1259
+ """
1260
+ Auxiliar variable determining the starting Y coordinate of the room
1261
+
1262
+ :return: Starting Y coordinate
1263
+ :rtype: float
1264
+ """
1006
1265
  return self.__start_y
1007
1266
 
1008
1267
  @start_y.setter
@@ -1010,7 +1269,13 @@ class Scenario:
1010
1269
  self.__start_y = value
1011
1270
 
1012
1271
  @property
1013
- def end_x(self):
1272
+ def end_x(self) -> float:
1273
+ """
1274
+ Auxiliar variable determining the ending X coordinate of the room
1275
+
1276
+ :return: Ending X coordinate
1277
+ :rtype: float
1278
+ """
1014
1279
  return self.__end_x
1015
1280
 
1016
1281
  @end_x.setter
@@ -1018,7 +1283,13 @@ class Scenario:
1018
1283
  self.__end_x = value
1019
1284
 
1020
1285
  @property
1021
- def end_y(self):
1286
+ def end_y(self) -> float:
1287
+ """
1288
+ Auxiliar variable determining the ending Y coordinate of the room
1289
+
1290
+ :return: Ending Y coordinate
1291
+ :rtype: float
1292
+ """
1022
1293
  return self.__end_y
1023
1294
 
1024
1295
  @end_y.setter
@@ -1026,7 +1297,13 @@ class Scenario:
1026
1297
  self.__end_y = value
1027
1298
 
1028
1299
  @property
1029
- def height(self):
1300
+ def height(self) -> float:
1301
+ """
1302
+ Scenario height
1303
+
1304
+ :return: Scenario height
1305
+ :rtype: float
1306
+ """
1030
1307
  return self.__height
1031
1308
 
1032
1309
  @height.setter
@@ -1034,7 +1311,13 @@ class Scenario:
1034
1311
  self.__height = value
1035
1312
 
1036
1313
  @property
1037
- def length(self):
1314
+ def length(self) -> float:
1315
+ """
1316
+ Scenario Length
1317
+
1318
+ :return: Scenario Length
1319
+ :rtype: float
1320
+ """
1038
1321
  return self.__length
1039
1322
 
1040
1323
  @length.setter
@@ -1042,7 +1325,13 @@ class Scenario:
1042
1325
  self.__length = value
1043
1326
 
1044
1327
  @property
1045
- def width(self):
1328
+ def width(self) -> float:
1329
+ """
1330
+ Scenario width
1331
+
1332
+ :return: Scenario width
1333
+ :rtype: float
1334
+ """
1046
1335
  return self.__width
1047
1336
 
1048
1337
  @width.setter
@@ -1050,14 +1339,36 @@ class Scenario:
1050
1339
  self.__width = value
1051
1340
 
1052
1341
  @property
1053
- def vledsPositions(self):
1342
+ def vledsPositions(self) -> list:
1343
+ """
1344
+ Vleds positions in room
1345
+
1346
+ :return: Vleds position
1347
+ :rtype: list
1348
+ """
1054
1349
  return self.__vledsPositions
1055
1350
 
1056
1351
  @property
1057
- def rfsPositions(self):
1352
+ def rfsPositions(self) -> list:
1353
+ """
1354
+ RFs positions
1355
+
1356
+ :return: RFs positions
1357
+ :rtype: list
1358
+ """
1058
1359
  return self.__rfsPositions
1059
1360
 
1060
1361
  def snrVled(self, receiver: Receiver, vled: VLed) -> float:
1362
+ """
1363
+ Total SNR in an specific point from a VLED, considering walls and positions.
1364
+
1365
+ :param receiver: Receiver device
1366
+ :type receiver: Receiver
1367
+ :param vled: VLED
1368
+ :type vled: VLed
1369
+ :return: Total SNR
1370
+ :rtype: float
1371
+ """
1061
1372
  powerReceived = self.getPowerInPointFromVled(
1062
1373
  receiver, vled.ID
1063
1374
  ) + self.getPowerInPointFromWalls(receiver, vled.ID)
@@ -1087,6 +1398,16 @@ class Scenario:
1087
1398
  return (receiver.s * powerReceived) ** 2 / rg
1088
1399
 
1089
1400
  def snrRf(self, receiver: Receiver, rf: RF) -> float:
1401
+ """
1402
+ Total SNR in an specific point from an RF.
1403
+
1404
+ :param receiver: Receiver device
1405
+ :type receiver: Receiver
1406
+ :param rf: RF device
1407
+ :type rf: RF
1408
+ :return: Total SNR
1409
+ :rtype: float
1410
+ """
1090
1411
  df = m.sqrt(
1091
1412
  (receiver.x - rf.x) ** 2
1092
1413
  + (receiver.y - rf.y) ** 2
@@ -1096,7 +1417,27 @@ class Scenario:
1096
1417
  return rf.pf * rf.Af * df ** (-rf.Ef)
1097
1418
 
1098
1419
  def capacityVled(self, receiver: Receiver, vled: VLed) -> float:
1420
+ """
1421
+ Capacity of the VLED channel considering receiver devices in an specific point.
1422
+
1423
+ :param receiver: Receiver device
1424
+ :type receiver: Receiver
1425
+ :param vled: VLED
1426
+ :type vled: VLed
1427
+ :return: Capacity
1428
+ :rtype: float
1429
+ """
1099
1430
  return vled.B * m.log2(1 + self.snrVled(receiver, vled))
1100
1431
 
1101
1432
  def capacityRf(self, receiver: Receiver, rf: RF) -> float:
1433
+ """
1434
+ Capacity of the RF channel considering receiver devices in an specific point.
1435
+
1436
+ :param receiver: Receiver device
1437
+ :type receiver: Receiver
1438
+ :param rf: RF
1439
+ :type rf: RF
1440
+ :return: Capacity
1441
+ :rtype: float
1442
+ """
1102
1443
  return rf.B * m.log2(1 + self.snrRf(receiver, rf))
@@ -1,30 +1,26 @@
1
+ """
2
+ The Module **Simulator** has all the Simulation Dynamics.
3
+ """
4
+
1
5
  from .controller import *
2
6
  from .scene import *
3
7
  import numpy as np
4
8
  from enum import Enum
5
9
 
6
- """
7
- The Module **Simulator** has all the Simulation Dynamics.
8
- """
9
-
10
10
 
11
11
  class Event:
12
- """This is a conceptual class representation of a simple BLE device
13
- (GATT Server). It is essentially an extended combination of the
14
-
15
- :param type: A handle to the :class:`simpleble.SimpleBleClient` client
16
- object that detected the device
17
- :type type: class:`Event.event`
18
- :param time: Device MAC address, defaults to None
19
- :type time: float, optional
20
- :param id_connection: Device address type - one of ADDR_TYPE_PUBLIC or
21
- ADDR_TYPE_RANDOM, defaults to ADDR_TYPE_PUBLIC
22
- :type id_connection: int, optional
12
+ """
13
+ The Event class has the information about the event, containing the time when the event occurs, the type of event, and the connection ID.
23
14
  """
24
15
 
25
16
  event = Enum("event", "ARRIVE DEPARTURE PAUSE RESUME NEXT_CONNECTION_TRY")
17
+ """
18
+ There are five event types. The **ARRIVE** event is used when a connection arrives to the scenario. **DEPARTURE** event when the connection leaves. **PAUSE** and **RESUME** is related to a connection that is currently served by an AP, but because of the frame-slot behavior is paused and resumed multiple times. Finally, **NEXT_CONNECTION_TRY** is used when a connection couldn't be stablished because capacity, and waits a random time and need to be served in future·
19
+ """
26
20
 
27
- def __init__(self, type=None, time=-1, id_connection=-1):
21
+ def __init__(
22
+ self, type: event = None, time: float = -1, id_connection: int = -1
23
+ ) -> None:
28
24
  self.__time = time
29
25
  self.__id_connection = id_connection
30
26
  if type == None:
@@ -34,28 +30,70 @@ class Event:
34
30
  self.__connection = None
35
31
 
36
32
  @property
37
- def type(self):
33
+ def type(self) -> event:
34
+ """
35
+ The connection type. Could be one of the fives types described before.
36
+
37
+ :return: Connection type
38
+ :rtype: event
39
+ """
38
40
  return self.__type
39
41
 
40
42
  @property
41
- def time(self):
43
+ def time(self) -> float:
44
+ """
45
+ The instant when this event occurs.
46
+
47
+ :return: Instant time of this event
48
+ :rtype: float
49
+ """
42
50
  return self.__time
43
51
 
44
52
  @property
45
- def id_connection(self):
53
+ def id_connection(self) -> int:
54
+ """
55
+ Connection ID of the connection related to this event
56
+
57
+ :return: Connection ID
58
+ :rtype: int
59
+ """
46
60
  return self.__id_connection
47
61
 
48
62
  @property
49
- def connection(self):
63
+ def connection(self) -> Connection:
64
+ """
65
+ Connection object related to this event.
66
+
67
+ :return: Connection object
68
+ :rtype: Connection
69
+ """
50
70
  return self.__connection
51
71
 
52
72
  @connection.setter
53
- def connection(self, value):
73
+ def connection(self, value: Connection):
54
74
  self.__connection = value
55
75
 
56
76
 
57
77
  class Simulator:
58
- def __init__(self, x, y, z, nGrids, rho):
78
+ """
79
+ Simulator class. In chanrge of randomness and the clock routine.
80
+ """
81
+
82
+ def __init__(self, x: float, y: float, z: float, nGrids: int, rho: float) -> None:
83
+ """
84
+ Simulator object constructor
85
+
86
+ :param x: Length of the scenario
87
+ :type x: float
88
+ :param y: Width of the scenario
89
+ :type y: float
90
+ :param z: Height of the scenario
91
+ :type z: float
92
+ :param nGrids: Number of segments on each dimension. Usefull for precision.
93
+ :type nGrids: int
94
+ :param rho: reflexion coefficient. A floating number between 0 and 1.
95
+ :type rho: float
96
+ """
59
97
  self.__controller = Controller(x, y, z, nGrids, rho)
60
98
  self.__events = []
61
99
  self.__current_event = None
@@ -98,6 +136,22 @@ class Simulator:
98
136
  self.default_values()
99
137
 
100
138
  def default_values(self):
139
+ """
140
+ Set the default simulation values, that are:
141
+
142
+ * lambdaS = 3
143
+ * mu = 10
144
+ * seedArrive = 12345
145
+ * seedDeparture = 1234
146
+ * seedX = 1235
147
+ * seedY = 1245
148
+ * seedZ = 1345
149
+ * seedRandomWait = 1345
150
+ * seedCapacityRequired = 1345
151
+ * goalConnections = 10000
152
+ * lower_random_wait = 5
153
+ * upper_random_wait = 15
154
+ """
101
155
  self.__initReady = False
102
156
  self.__lambdaS = 3
103
157
  self.__mu = 10
@@ -113,9 +167,16 @@ class Simulator:
113
167
  self.__goalConnections = 10000
114
168
  self.__lower_random_wait = 5
115
169
  self.__upper_random_wait = 15
170
+ self.__controller.allocator = Controller.default_alloc
116
171
 
117
172
  @property
118
- def upper_capacity_required(self):
173
+ def upper_capacity_required(self) -> float:
174
+ """
175
+ The upper possible capacity required
176
+
177
+ :return: Upper capacity required
178
+ :rtype: float
179
+ """
119
180
  return self.__upper_capacity_required
120
181
 
121
182
  @upper_capacity_required.setter
@@ -123,7 +184,13 @@ class Simulator:
123
184
  self.__upper_capacity_required = value
124
185
 
125
186
  @property
126
- def lower_capacity_required(self):
187
+ def lower_capacity_required(self) -> float:
188
+ """
189
+ The lower possible capacity required
190
+
191
+ :return: Lower capacity required
192
+ :rtype: float
193
+ """
127
194
  return self.__lower_capacity_required
128
195
 
129
196
  @lower_capacity_required.setter
@@ -132,6 +199,12 @@ class Simulator:
132
199
 
133
200
  @property
134
201
  def seedCapacityRequired(self) -> int:
202
+ """
203
+ Seed of capacity required random generator
204
+
205
+ :return: random generator seed
206
+ :rtype: int
207
+ """
135
208
  return self.__seedCapacityRequired
136
209
 
137
210
  @seedCapacityRequired.setter
@@ -139,7 +212,13 @@ class Simulator:
139
212
  self.__seedCapacityRequired = value
140
213
 
141
214
  @property
142
- def upper_random_wait(self):
215
+ def upper_random_wait(self) -> float:
216
+ """
217
+ the upper possible random wait
218
+
219
+ :return: upper waiting time
220
+ :rtype: float
221
+ """
143
222
  return self.__upper_random_wait
144
223
 
145
224
  @upper_random_wait.setter
@@ -147,7 +226,13 @@ class Simulator:
147
226
  self.__upper_random_wait = value
148
227
 
149
228
  @property
150
- def lower_random_wait(self):
229
+ def lower_random_wait(self) -> float:
230
+ """
231
+ The lower possible random wait
232
+
233
+ :return: lower waiting time
234
+ :rtype: float
235
+ """
151
236
  return self.__lower_random_wait
152
237
 
153
238
  @lower_random_wait.setter
@@ -155,9 +240,12 @@ class Simulator:
155
240
  self.__lower_random_wait = value
156
241
 
157
242
  @property
158
- def lambdaS(self):
243
+ def lambdaS(self) -> float:
159
244
  """
160
245
  Get or set the attribute lambda.
246
+
247
+ :return: lambda attribute
248
+ :rtype: float
161
249
  """
162
250
  return self.__lambdaS
163
251
 
@@ -171,9 +259,12 @@ class Simulator:
171
259
  self.__lambdaS = lambdaS
172
260
 
173
261
  @property
174
- def mu(self):
262
+ def mu(self) -> float:
175
263
  """
176
264
  Get or set the attribute mu.
265
+
266
+ :return: mu attribute
267
+ :rtype: float
177
268
  """
178
269
  return self.__mu
179
270
 
@@ -187,9 +278,12 @@ class Simulator:
187
278
  self.__mu = mu
188
279
 
189
280
  @property
190
- def seedX(self):
281
+ def seedX(self) -> int:
191
282
  """
192
- Get or set the attribute seedArrive.
283
+ Get or set the attribute seedX.
284
+
285
+ :return: the seed of random X generator
286
+ :rtype: int
193
287
  """
194
288
  return self.__seedX
195
289
 
@@ -203,9 +297,12 @@ class Simulator:
203
297
  self.__seedX = seedX
204
298
 
205
299
  @property
206
- def seedY(self):
300
+ def seedY(self) -> int:
207
301
  """
208
- Get or set the attribute seedDeparture.
302
+ Get or set the attribute seedY.
303
+
304
+ :return: the seed of random Y generator
305
+ :rtype: int
209
306
  """
210
307
  return self.__seedY
211
308
 
@@ -219,9 +316,12 @@ class Simulator:
219
316
  self.__seedY = seedY
220
317
 
221
318
  @property
222
- def seedZ(self):
319
+ def seedZ(self) -> int:
223
320
  """
224
- Get or set the attribute seedBitRate.
321
+ Get or set the attribute seedZ.
322
+
323
+ :return: the seed of random Z generator
324
+ :rtype: int
225
325
  """
226
326
  return self.__seedZ
227
327
 
@@ -235,9 +335,12 @@ class Simulator:
235
335
  self.__seedZ = seedZ
236
336
 
237
337
  @property
238
- def seedRandomWait(self):
338
+ def seedRandomWait(self) -> int:
239
339
  """
240
- Get or set the attribute seedBitRate.
340
+ Get or set the attribute seedRandomWait.
341
+
342
+ :return: the seed of random random-wait generator
343
+ :rtype: int
241
344
  """
242
345
  return self.__seedRandomWait
243
346
 
@@ -251,9 +354,12 @@ class Simulator:
251
354
  self.__seedRandomWait = seedRandomWait
252
355
 
253
356
  @property
254
- def goalConnections(self):
357
+ def goalConnections(self) -> int:
255
358
  """
256
359
  Get or set the attribute goalConnections.
360
+
361
+ :return: The goal connections
362
+ :rtype: int
257
363
  """
258
364
  return self.__goalConnections
259
365
 
@@ -267,6 +373,9 @@ class Simulator:
267
373
  self.__goalConnections = goalConnections
268
374
 
269
375
  def print_initial_info(self):
376
+ """
377
+ Prints the initial info of simulation.
378
+ """
270
379
  print(
271
380
  "Scenario:\t %s x %s x %s"
272
381
  % (
@@ -314,6 +423,12 @@ class Simulator:
314
423
  print("=" * 146)
315
424
 
316
425
  def print_row(self, event):
426
+ """
427
+ print every simulation row
428
+
429
+ :param event: The event to print_
430
+ :type event: Event
431
+ """
317
432
  text = ""
318
433
  text = "{:9.4f}".format(event.time) + "|"
319
434
  if event.type == Event.event.ARRIVE:
@@ -372,6 +487,9 @@ class Simulator:
372
487
  print(text)
373
488
 
374
489
  def event_routine(self):
490
+ """
491
+ The event routine. This function selects the event and run the associated routine.
492
+ """
375
493
  self.__current_event = self.__events[0]
376
494
  self.__rtn_allocation = None
377
495
  self.__clock = self.__current_event.time
@@ -550,11 +668,13 @@ class Simulator:
550
668
  # self.__events.insert(pos + 1, e)
551
669
  # break
552
670
  self.__events.pop(0)
553
- self.print_row(self.__current_event)
554
671
 
555
672
  return self.__rtn_allocation
556
673
 
557
674
  def init(self):
675
+ """
676
+ Simulation init. Initialize every simulation parameter.
677
+ """
558
678
  self.__initReady = True
559
679
  self.__clock = 0
560
680
  self.__arrival_variable = np.random.default_rng(self.__seedArrive)
@@ -586,29 +706,59 @@ class Simulator:
586
706
  return
587
707
 
588
708
  def run(self):
709
+ """
710
+ Run this simulation with the parameters.
711
+ """
589
712
  self.print_initial_info()
590
713
  while self.__numberOfConnections <= self.__goalConnections:
591
714
  # for i in range(self.__goalConnections):
592
715
  self.event_routine()
716
+ self.print_row(self.__current_event)
593
717
  self.aggregated_metrics()
594
718
 
595
- def time_duration(self):
719
+ def time_duration(self) -> float:
720
+ """
721
+ Duration time
722
+
723
+ :return: duration time
724
+ :rtype: float
725
+ """
596
726
  return self.__time_duration
597
727
 
598
- def get_Blocking_Probability(self):
728
+ def get_Blocking_Probability(self) -> float:
729
+ """
730
+ Blocking probability
731
+
732
+ :return: blocking probability
733
+ :rtype: float
734
+ """
599
735
  blocking = round(
600
736
  1 - self.__allocatedConnections / self.__numberOfConnections, 2
601
737
  )
602
738
  return blocking
603
739
 
604
740
  def set_allocation_algorithm(self, alloc_alg):
741
+ """
742
+ Set allocation algorithm.
743
+
744
+ :param alloc_alg: Allocation algorithm
745
+ """
605
746
  self.__controller.allocator = alloc_alg
606
747
 
607
748
  @property
608
749
  def scenario(self):
750
+ """
751
+ Scenario used in this simulation
752
+
753
+ :return: Scenario
754
+ :rtype: Scenario
755
+ """
609
756
  return self.__controller.scenario
610
757
 
611
758
  def aggregated_metrics(self):
759
+ """
760
+ Number of users connected to each AP
761
+ """
612
762
  print("Number of users connected to each VLed")
613
763
  for i in range(self.__controller.scenario.numberOfVLeds):
614
764
  id = self.__controller.scenario.vleds[i].ID
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes