netrl 0.1.0__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.
Files changed (47) hide show
  1. netrl-0.1.0/LICENSE +279 -0
  2. netrl-0.1.0/PKG-INFO +311 -0
  3. netrl-0.1.0/README.md +290 -0
  4. netrl-0.1.0/docs/conf.py +80 -0
  5. netrl-0.1.0/examples/cartpole_5g.py +38 -0
  6. netrl-0.1.0/examples/cartpole_5g_lena.py +40 -0
  7. netrl-0.1.0/examples/cartpole_example.py +38 -0
  8. netrl-0.1.0/examples/cartpole_ge.py +34 -0
  9. netrl-0.1.0/examples/cartpole_multi_view.py +155 -0
  10. netrl-0.1.0/examples/cartpole_wifi_multi_ue.py +126 -0
  11. netrl-0.1.0/examples/example_fast_channel.py +127 -0
  12. netrl-0.1.0/examples/example_networkenv_fast_channel.py +169 -0
  13. netrl-0.1.0/examples/image_observations.py +44 -0
  14. netrl-0.1.0/examples/parallel_env.py +26 -0
  15. netrl-0.1.0/examples/sb3_train.py +21 -0
  16. netrl-0.1.0/netrl/__init__.py +114 -0
  17. netrl-0.1.0/netrl/central_node.py +200 -0
  18. netrl-0.1.0/netrl/channels/comm_channel.py +182 -0
  19. netrl-0.1.0/netrl/channels/network_config.py +68 -0
  20. netrl-0.1.0/netrl/channels/ns3_channel.py +408 -0
  21. netrl-0.1.0/netrl/channels/ns3_channel_fast.py +159 -0
  22. netrl-0.1.0/netrl/channels/ns3_lena_channel.py +267 -0
  23. netrl-0.1.0/netrl/channels/ns3_lena_config.py +59 -0
  24. netrl-0.1.0/netrl/channels/ns3_mmwave_channel.py +412 -0
  25. netrl-0.1.0/netrl/channels/ns3_mmwave_config.py +159 -0
  26. netrl-0.1.0/netrl/channels/ns3_multi_ue_channel.py +580 -0
  27. netrl-0.1.0/netrl/channels/ns3_wifi_config.py +100 -0
  28. netrl-0.1.0/netrl/channels/ns3_wifi_fast_config.py +60 -0
  29. netrl-0.1.0/netrl/channels/ns3_wifi_multi_ue_config.py +96 -0
  30. netrl-0.1.0/netrl/multi_view_networked_env.py +365 -0
  31. netrl-0.1.0/netrl/netrl_ext.py +52 -0
  32. netrl-0.1.0/netrl/netrl_multi_ue_ext.py +52 -0
  33. netrl-0.1.0/netrl/networked_env.py +275 -0
  34. netrl-0.1.0/netrl/utils/image_env_wrapper.py +35 -0
  35. netrl-0.1.0/netrl/utils/multi_view_model.py +31 -0
  36. netrl-0.1.0/netrl/utils/observation_buffer.py +166 -0
  37. netrl-0.1.0/netrl.egg-info/PKG-INFO +311 -0
  38. netrl-0.1.0/netrl.egg-info/SOURCES.txt +45 -0
  39. netrl-0.1.0/netrl.egg-info/dependency_links.txt +1 -0
  40. netrl-0.1.0/netrl.egg-info/requires.txt +8 -0
  41. netrl-0.1.0/netrl.egg-info/top_level.txt +10 -0
  42. netrl-0.1.0/pyproject.toml +31 -0
  43. netrl-0.1.0/setup.cfg +4 -0
  44. netrl-0.1.0/setup.py +172 -0
  45. netrl-0.1.0/src/netcomm.cpp +319 -0
  46. netrl-0.1.0/src/ns3_wifi_channel_pybind11.cpp +465 -0
  47. netrl-0.1.0/src/ns3_wifi_multi_ue_channel_pybind11.cpp +305 -0
netrl-0.1.0/LICENSE ADDED
@@ -0,0 +1,279 @@
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+
7
+ Everyone is permitted to copy and distribute verbatim copies
8
+ of this license document, but changing it is not allowed.
9
+
10
+ PREAMBLE
11
+
12
+ The licenses for most software are designed to take away your
13
+ freedom to share and change it. By contrast, the GNU General
14
+ Public License is intended to guarantee your freedom to share
15
+ and change free software--to make sure the software is free for
16
+ all its users. This General Public License applies to most of
17
+ the Free Software Foundation's software and to any other program
18
+ whose authors commit to using it. (Some other Free Software
19
+ Foundation software is covered by the GNU Lesser General Public
20
+ License instead.) You can apply it to your programs, too.
21
+
22
+ When we speak of free software, we are referring to freedom, not
23
+ price. Our General Public Licenses are designed to make sure that
24
+ you have the freedom to distribute copies of free software (and
25
+ charge for this service if you wish), that you receive source code
26
+ or can get it if you want it, that you can change the software or
27
+ use pieces of it in new free programs; and that you know you can
28
+ do these things.
29
+
30
+ To protect your rights, we need to make restrictions that forbid
31
+ anyone to deny you these rights or to ask you to surrender the rights.
32
+ These restrictions translate to certain responsibilities for you if
33
+ you distribute copies of the software, or if you modify it.
34
+
35
+ For example, if you distribute copies of such a program, whether
36
+ gratis or for a fee, you must give the recipients all the rights
37
+ that you have. You must make sure that they, too, receive or can
38
+ get the source code. And you must show them these terms so they
39
+ know their rights.
40
+
41
+ We protect your rights with two steps: (1) copyright the software, and
42
+ (2) offer you this license which gives you legal permission to copy,
43
+ distribute and/or modify the software.
44
+
45
+ Also, for each author's protection and ours, we want to make certain
46
+ that everyone understands that there is no warranty for this free
47
+ software. If the software is modified by someone else and passed on, we
48
+ want its recipients to know that what they have is not the original, so
49
+ that any problems introduced by others will not reflect on the original
50
+ authors' reputations.
51
+
52
+ Finally, any free program is threatened constantly by software
53
+ patents. We wish to avoid the danger that redistributors of a free
54
+ program will individually obtain patent licenses, in effect making the
55
+ program proprietary. To prevent this, we have made it clear that any
56
+ patent must be licensed for everyone's free use or not licensed at all.
57
+
58
+ The precise terms and conditions for copying, distribution and
59
+ modification follow.
60
+
61
+ TERMS AND CONDITIONS
62
+
63
+ 0. This License applies to any program or other work which contains
64
+ a notice placed by the copyright holder saying it may be distributed
65
+ under the terms of this General Public License. The "Program", below,
66
+ refers to any such program or work, and a "work based on the Program"
67
+ means either the Program or any work containing the Program or a portion
68
+ of it, either verbatim or with modifications and/or translated into
69
+ another language. (Hereinafter, translation is included without limitation
70
+ in the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the Program
76
+ (independent of having been made by running the Program). Whether that
77
+ is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or a work based on the Program) on a volume of a
131
+ storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at
143
+ least three years, to give any third party, for a charge no
144
+ more than your cost of physically performing source distribution, a
145
+ complete machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties with
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is to apply in other circumstances.
213
+
214
+ It is not the purpose of this section to induce you to infringe any
215
+ patents or other property right claims or to contest validity of any
216
+ such claims; this section has the sole purpose of protecting the
217
+ integrity of the free software distribution system, which is
218
+ implemented by public license practices. Many people have made
219
+ generous contributions to the wide range of software distributed
220
+ through that system in reliance on consistent application of that
221
+ system; it is up to the author/donor to decide if he or she is willing
222
+ to distribute software through any other system and a licensee cannot
223
+ impose that choice.
224
+
225
+ This section is intended to make thoroughly clear what is believed to
226
+ be a consequence of the rest of this License.
227
+
228
+ 8. If the distribution and/or use of the Program is restricted in
229
+ certain countries either by patents or by copyrighted interfaces, the
230
+ original copyright holder who places the Program under this License
231
+ may add an explicit geographical distribution limitation excluding
232
+ those countries, so that distribution is permitted only in or among
233
+ countries not thus excluded. In such case, this License incorporates
234
+ the limitation as if written in the body of this License.
235
+
236
+ 9. The Free Software Foundation may publish revised and/or new versions
237
+ of the General Public License from time to time. Such new versions will
238
+ be similar in spirit to the present version, but may differ in detail to
239
+ address new problems or concerns.
240
+
241
+ Each version is given a distinguishing version number. If the Program
242
+ specifies a version number of this License which applies to it and "any
243
+ later version", you have the option of following the terms and conditions
244
+ either of that version or of any later version published by the Free
245
+ Software Foundation. If the Program does not specify a version number of
246
+ this License, you may choose any version ever published by the Free
247
+ Software Foundation.
248
+
249
+ 10. If you wish to incorporate parts of the Program into other free
250
+ programs whose distribution conditions are incompatible with these, write
251
+ to the author to ask for permission. For software which is copyrighted
252
+ by the Free Software Foundation, write to the Free Software Foundation;
253
+ we sometimes make exceptions for this. Our decision will be guided by
254
+ the two goals of preserving the free status of all derivative works of
255
+ our free software and of promoting the sharing and reusefulness of
256
+ software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSS OF PROFITS OR
276
+ LOSS OF SAVINGS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
277
+ THE POSSIBILITY OF SUCH DAMAGES.
278
+
279
+ END OF TERMS AND CONDITIONS
netrl-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,311 @@
1
+ Metadata-Version: 2.4
2
+ Name: netrl
3
+ Version: 0.1.0
4
+ Summary: Networked RL simulation platform — gymnasium wrapper with communication channel simulation.
5
+ Author-email: Pietro Talli <pietrotalli@gmail.com>
6
+ License-Expression: GPL-2.0-only
7
+ Project-URL: Homepage, https://github.com/pietro-talli/NetRL
8
+ Project-URL: Documenation, https://netrl.readthedocs.io/en/latest/index.html
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: gymnasium>=0.29
13
+ Requires-Dist: numpy>=1.24
14
+ Requires-Dist: pybind11>=2.11
15
+ Requires-Dist: ns3>=3.44.post
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest>=7.0; extra == "dev"
18
+ Requires-Dist: matplotlib>=3.7; extra == "dev"
19
+ Dynamic: license-file
20
+ Dynamic: requires-python
21
+
22
+ # NetRL — Networked Reinforcement Learning Simulation Platform
23
+
24
+ NetRL wraps any [Gymnasium](https://gymnasium.farama.org/) environment and simulates a **noisy communication channel** between the agent and the environment. At every `step()`, the raw observation is transmitted through a configurable channel backend (loss, delay, retransmissions). The agent receives a **sliding-window buffer** of past observations together with a boolean mask indicating which slots actually arrived.
25
+
26
+ Full documentation: https://netrl.readthedocs.io/en/latest/index.html
27
+
28
+ Four channel backends are available:
29
+
30
+ | Backend | Model | Config class | Requires |
31
+ |---|---|---|---|
32
+ | **Gilbert-Elliott** (default) | Two-state Markov chain with configurable loss per state and fixed delay | `NetworkConfig` | Built-in |
33
+ | **ns-3 802.11a WiFi (fast)** ⚡ | Full MAC/PHY simulation via ns-3 — same physics as below but compiled as a Python C++ extension (pybind11), **no subprocess overhead** | `NS3WiFiChannelFastConfig` | `pip install ns3` — built automatically |
34
+ | **ns-3 802.11a WiFi** | Full MAC/PHY simulation via ns-3 — CSMA/CA, retransmissions, path-loss | `NS3WifiConfig` | `pip install ns3` + manual binary build |
35
+ | **ns-3 5G mmWave** | Full EPC/NR simulation via ns-3-mmwave — 3GPP TR 38.901 path-loss, HARQ, RLC | `NS3MmWaveConfig` | ns-3-mmwave source build |
36
+ | **ns-3 5G-LENA NR** | Full NR + EPC simulation via 5G-LENA (contrib/nr) — 3GPP channel, beamforming, numerology | `NS3LenaConfig` | 5G-LENA source build |
37
+
38
+ > **Recommendation:** Use `NS3WiFiChannelFastConfig` for all 802.11a WiFi experiments. It provides identical physical simulation to `NS3WifiConfig` but runs **2-3× faster** by eliminating subprocess IPC overhead — and it is compiled automatically when you run `pip install -e .`.
39
+
40
+ ---
41
+
42
+ ## Table of Contents
43
+
44
+ 1. [Requirements](#requirements)
45
+ 2. [Installation](#installation)
46
+ - [Python package, GE channel, and fast WiFi channel](#1-python-package-ge-channel-and-fast-wifi-channel)
47
+ - [ns-3 WiFi binary (subprocess version)](#2-ns-3-wifi-binary-subprocess-version)
48
+ - [ns-3 5G mmWave binary](#3-ns-3-5g-mmwave-binary)
49
+ - [ns-3 5G-LENA binary](#4-ns-3-5g-lena-binary)
50
+ 3. [Quick Start](#quick-start)
51
+ - [Gilbert-Elliott channel](#gilbert-elliott-channel)
52
+ - [ns-3 WiFi channel (fast — recommended)](#ns-3-wifi-channel-fast--recommended)
53
+ - [ns-3 WiFi channel (subprocess)](#ns-3-wifi-channel-subprocess)
54
+ - [ns-3 5G mmWave channel](#ns-3-5g-mmwave-channel)
55
+ - [ns-3 5G-LENA channel](#ns-3-5g-lena-channel)
56
+ 4. [Observation Space](#observation-space)
57
+
58
+ ---
59
+
60
+ ## Requirements
61
+
62
+ - Python ≥ 3.10
63
+ - GCC ≥ 10 or Clang ≥ 11
64
+ - C++20 for the pybind11 extensions (`netcomm` GE channel and `netrl_ext` fast WiFi channel)
65
+ - **C++20** for the ns-3 mmWave binary (ns-3-mmwave 3.42 uses `std::remove_cvref_t`)
66
+ - For the fast WiFi channel and the subprocess WiFi channel:
67
+ - `pip install ns3` (ns-3 ≥ 3.43, headers + shared libs) — the **fast WiFi channel is built automatically** during `pip install -e .`
68
+ - For the 5G mmWave channel:
69
+ - A compiled **ns-3-mmwave** source build at `/path/to/ns3-mmwave/build` (ns-3 3.42)
70
+
71
+ ---
72
+
73
+ ## Installation
74
+
75
+ ### 1. Python package, GE channel, and fast WiFi channel
76
+
77
+ The Gilbert-Elliott channel (`netcomm`) and the fast ns-3 WiFi channel (`_netrl_ext`) are both compiled as C++ pybind11 extensions. Install everything with a single command:
78
+
79
+ ```bash
80
+ pip install -e .
81
+ ```
82
+
83
+ This automatically:
84
+ 1. Installs all Python dependencies (including `ns3 ≥ 3.44`)
85
+ 2. Compiles `netcomm` — the Gilbert-Elliott C++ backend
86
+ 3. Detects the pip-installed `ns3` library and **compiles `_netrl_ext`** — the fast WiFi pybind11 binding
87
+
88
+ The fast WiFi channel (`NS3WiFiChannelFastConfig`) is then immediately available — no extra build step required.
89
+
90
+ ```python
91
+ from netrl import NetworkedEnv, NetworkConfig, NS3WiFiChannelFastConfig
92
+ ```
93
+
94
+ ### 2. ns-3 WiFi binary (subprocess version)
95
+
96
+ The subprocess ns-3 backend runs the simulation in a **separate process** and communicates via stdin/stdout pipes. Compile the binary once before use:
97
+
98
+ ```bash
99
+ bash src/build_ns3_sim.sh
100
+ ```
101
+
102
+ The script auto-detects your ns-3 installation, compiles `src/ns3_wifi_sim.cc`, and writes the binary to `src/ns3_wifi_sim`.
103
+
104
+ ### 3. ns-3 5G mmWave binary
105
+
106
+ The mmWave backend requires a separate binary built against [ns-3-mmwave](https://github.com/nyuwireless-unipd/ns3-mmwave) (ns-3 3.42). Compile it once before use:
107
+
108
+ ```bash
109
+ bash src/build_ns3_mmwave_sim.sh --ns3-mmwave-dir /path/to/ns3-mmwave
110
+ ```
111
+
112
+ The script expects ns-3-mmwave to be built at `/home/dianalab/Projects/ns3-mmwave/build` (edit the `NS3_MMWAVE_BUILD` variable at the top of the script to change the path).
113
+
114
+ ### 4. ns-3 5G-LENA binary
115
+
116
+ The 5G-LENA backend requires a separate binary built against your local 5G-LENA tree (contrib/nr). Compile it once before use:
117
+
118
+ ```bash
119
+ bash src/build_ns3_lena_sim.sh --ns3-lena-dir /path/to/5g-lena/ns-3-dev
120
+ ```
121
+
122
+ By default, the script expects 5G-LENA at `/home/dianalab/Projects/5g-lena/ns-3-dev`.
123
+
124
+ ## Quick Start
125
+
126
+ ### Gilbert-Elliott channel
127
+
128
+ ```python
129
+ import gymnasium as gym
130
+ from netrl import NetworkedEnv, NetworkConfig
131
+
132
+ config = NetworkConfig(
133
+ p_gb=0.1, # Good -> Bad transition probability per step
134
+ p_bg=0.3, # Bad -> Good transition probability per step
135
+ loss_good=0.01, # packet loss probability in Good state
136
+ loss_bad=0.20, # packet loss probability in Bad state
137
+ delay_steps=3, # fixed one-way delay in env steps
138
+ buffer_size=10, # observation window length
139
+ seed=42,
140
+ )
141
+
142
+ env = NetworkedEnv(gym.make("CartPole-v1"), config)
143
+ obs, info = env.reset()
144
+
145
+ # obs["observations"].shape == (10, 4) — buffer of last 10 obs
146
+ # obs["recv_mask"].shape == (10,) — True where a packet arrived
147
+
148
+ for _ in range(1000):
149
+ obs, reward, term, trunc, info = env.step(env.action_space.sample())
150
+ print(info["channel_info"]["state"]) # "GOOD" or "BAD"
151
+ print(info["arrived_this_step"]) # True / False
152
+ if term or trunc:
153
+ obs, info = env.reset()
154
+ ```
155
+
156
+ ### ns-3 WiFi channel
157
+
158
+ ```python
159
+ import gymnasium as gym
160
+ from netrl import NetworkedEnv, NetworkConfig, NS3WiFiChannelFastConfig
161
+
162
+ env = NetworkedEnv(
163
+ gym.make("CartPole-v1"),
164
+ NetworkConfig(buffer_size=10, seed=42),
165
+ channel_config=NS3WiFiChannelFastConfig(
166
+ distance_m=20.0, # STA-to-AP distance
167
+ step_duration_ms=5.0, # 5 ms of ns-3 time per env step
168
+ tx_power_dbm=20.0,
169
+ loss_exponent=3.0,
170
+ max_retries=7,
171
+ packet_size_bytes=256,
172
+ ),
173
+ )
174
+
175
+ obs, info = env.reset()
176
+
177
+ for _ in range(1000):
178
+ obs, reward, term, trunc, info = env.step(env.action_space.sample())
179
+ print(info["channel_info"]["state"]) # "NS3_WIFI"
180
+ if term or trunc:
181
+ obs, info = env.reset()
182
+ ```
183
+
184
+ > **No subprocess, no binary to build.** The `netrl_ext` extension is compiled automatically during `pip install -e .` and linked directly into the Python process. Performance is **2-3× faster** than the subprocess variant, with lower memory usage and instant startup.
185
+
186
+ ### ns-3 WiFi channel (subprocess)
187
+
188
+ ```python
189
+ import gymnasium as gym
190
+ from netrl import NetworkedEnv, NetworkConfig, NS3WifiConfig
191
+
192
+ env = NetworkedEnv(
193
+ gym.make("CartPole-v1"),
194
+ NetworkConfig(buffer_size=10),
195
+ channel_config=NS3WifiConfig(
196
+ distance_m=20.0, # STA-to-AP distance
197
+ step_duration_ms=5.0, # 5 ms of ns-3 time per env step
198
+ tx_power_dbm=20.0,
199
+ loss_exponent=3.0,
200
+ max_retries=7,
201
+ packet_size_bytes=256,
202
+ ),
203
+ )
204
+
205
+ obs, info = env.reset()
206
+
207
+ for _ in range(1000):
208
+ obs, reward, term, trunc, info = env.step(env.action_space.sample())
209
+ print(info["channel_info"]["state"]) # "NS3_WIFI"
210
+ if term or trunc:
211
+ obs, info = env.reset()
212
+ ```
213
+
214
+ > The ns-3 simulation is **persistent across steps** — MAC-layer state (backoff counters, retry timers) carries over between steps, giving temporally correlated, realistic channel behaviour. The simulation is only rebuilt on `env.reset()`.
215
+
216
+ ### ns-3 5G mmWave channel
217
+
218
+ ```python
219
+ import gymnasium as gym
220
+ from netrl import NetworkedEnv, NetworkConfig, NS3MmWaveConfig
221
+
222
+ env = NetworkedEnv(
223
+ gym.make("CartPole-v1"),
224
+ NetworkConfig(buffer_size=10),
225
+ channel_config=NS3MmWaveConfig(
226
+ distance_m=50.0, # UE-to-eNB distance
227
+ frequency_ghz=28.0, # 28 GHz (n257/n261 band)
228
+ bandwidth_ghz=0.2, # 200 MHz component carrier
229
+ tx_power_dbm=23.0, # UE transmit power
230
+ scenario="UMa", # Urban Macro (3GPP TR 38.901)
231
+ harq_enabled=True,
232
+ step_duration_ms=1.0,
233
+ packet_size_bytes=64,
234
+ ),
235
+ )
236
+
237
+ obs, info = env.reset()
238
+
239
+ for _ in range(1000):
240
+ obs, reward, term, trunc, info = env.step(env.action_space.sample())
241
+ print(info["channel_info"]["state"]) # "NS3_MMWAVE"
242
+ if term or trunc:
243
+ obs, info = env.reset()
244
+ ```
245
+
246
+ > The mmWave simulation models a full 5G EPC stack (UE → eNB → SGW/PGW → remote host) with 3GPP TR 38.901 path-loss, HARQ retransmissions, and configurable RLC mode. The first `reset()` call waits up to 60 s for the EPC to initialise — subsequent resets are faster.
247
+
248
+ ### ns-3 5G-LENA channel
249
+
250
+ ```python
251
+ import gymnasium as gym
252
+ from netrl import NetworkedEnv, NetworkConfig, NS3LenaConfig
253
+
254
+ env = NetworkedEnv(
255
+ gym.make("CartPole-v1"),
256
+ NetworkConfig(buffer_size=10),
257
+ channel_config=NS3LenaConfig(
258
+ distance_m=80.0,
259
+ frequency_ghz=28.0,
260
+ bandwidth_ghz=0.1,
261
+ scenario="UMa",
262
+ numerology=3,
263
+ step_duration_ms=2.0,
264
+ ),
265
+ )
266
+
267
+ obs, info = env.reset()
268
+ for _ in range(1000):
269
+ obs, reward, term, trunc, info = env.step(env.action_space.sample())
270
+ print(info["channel_info"]["state"]) # "NS3_LENA"
271
+ if term or trunc:
272
+ obs, info = env.reset()
273
+ ```
274
+
275
+ > The 5G-LENA simulation is persistent across steps and only rebuilt on `env.reset()`. It uses the same NetRL subprocess protocol as the WiFi and mmWave backends.
276
+
277
+ ---
278
+
279
+ ## Observation Space
280
+
281
+ `NetworkedEnv` replaces the wrapped env's `Box` observation space with:
282
+
283
+ ```python
284
+ gymnasium.spaces.Dict({
285
+ "observations": Box(
286
+ shape=(buffer_size, *original_obs_shape),
287
+ dtype=original_obs_dtype,
288
+ ),
289
+ "recv_mask": MultiBinary(buffer_size),
290
+ })
291
+ ```
292
+
293
+ - `observations[-1]` is the **most recent** slot; `observations[0]` is the oldest.
294
+ - Slots where no packet arrived (dropped or not yet delivered) are zero-filled with `recv_mask = False`.
295
+ - The buffer always has exactly `buffer_size` entries, providing a **fixed-shape input** for neural network policies.
296
+
297
+ The `info` dict returned by `step()` is augmented with:
298
+
299
+ | Key | Type | Description |
300
+ |---|---|---|
301
+ | `"channel_info"` | `dict` | Diagnostic snapshot from the channel backend |
302
+ | `"arrived_this_step"` | `bool` | `True` if at least one packet arrived during this step |
303
+
304
+ **GE `channel_info` keys:** `state` (`"GOOD"` / `"BAD"`), `pending_count`
305
+
306
+ **ns-3 fast WiFi `channel_info` keys:** `state` (`"NS3_WIFI"`), `distance_m`, `step_duration_ms`, `tx_power_dbm`, `loss_exponent`, `max_retries`, `packet_size_bytes`, `pending_tx_count`, `pending_rx_count`
307
+
308
+ **ns-3 WiFi `channel_info` keys:** `state` (`"NS3_WIFI"`), `pending_count`, `arrived_buffered`, `distance_m`, `step_duration_ms`, `tx_power_dbm`, `loss_exponent`, `max_retries`
309
+
310
+ **ns-3 mmWave `channel_info` keys:** `state` (`"NS3_MMWAVE"`), `pending_count`, `arrived_buffered`, `distance_m`, `frequency_ghz`, `bandwidth_ghz`, `tx_power_dbm`, `enb_tx_power_dbm`, `noise_figure_db`, `scenario`, `harq_enabled`, `rlc_am_enabled`, `step_duration_ms`
311
+