[[Include(/WikiToC)]] = Massive MIMO Channel Sounding = === Description === In this tutorial, we demonstrate the TDD 16x1 Massive MIMO channel sounding procedure using 1 Massive MIMO rack (8 USRP-X310s) and 1 USRP-B210 in the [https://www.orbit-lab.org/wiki/Hardware/bDomains/aGrid ORBIT grid] and the [https://github.com/renew-wireless/RENEWLab/ RENEW Sounder software] * The instructions of the RENEW Platform Sounder software can be found [https://docs.renew-wireless.org/dev-suite/design-flows/cpp/sounder/ here] under [https://docs.renew-wireless.org/license/ RENEW license]. * The COSMOS team contributes to adding the UHD support for the Sounder software under the [https://github.com/EttusResearch/uhd/blob/master/LICENSE.md UHD license]. We thank the RENEW team for the support and help throughout the process. Authors: \\ Zhenzhou (Tom) Qi, Duke University \\ Tingjun Chen, Duke University Last updated: August 8, 2022 === Prerequisites === In order to access grid, create a reservation in grid and have it approved by the reservation service. Access to the resources is granted after the reservation is confirmed. Please follow the process shown on the COSMOS getting [https://wiki.cosmos-lab.org/wiki/GettingStarted started page] to get started. === Resources Required === * 1 Massive MIMO Rack ({{{node23-1}}} to {{{node23-8}}}) * 1 USRP-B210 ({{{node8-7}}}) * 1 Server ({{{node21-1}}}) === Tutorial Setup === Follow the steps below to gain access to the grid console and set up nodes with appropriate images. 1. If you don't have one already, sign up for a [https://www.orbit-lab.org/userManagement/register ORBIT account] 1. [wiki:/GettingStarted#MakeaReservation Create a resource reservation] on ORBIT grid 1. [Documentation/Short/Login Login] into grid console ({{{grid.orbit-lab.org}}}) with two SSH sessions. 1. Make sure all the nodes and devices used in the experiment are turned off {{{#!shell omf tell -a offh -t node21-1,node8-7 }}} {{{#!shell omf tell -a offh -t [23,1..8] }}} 1. Use the {{{ubuntu2004-uhd4.1-gr3.9.ndz}}} node image with Ubuntu 20.04, UHD 4.10, and gnuradio 3.9. Load {{{ubuntu2004-uhd4.1-gr3.9.ndz}}} on both the server and ({{{node8-7}}}). {{{#!shell omf load -i ubuntu2004-uhd4.1-gr3.9.ndz -t node21-1 }}} {{{#!shell omf load -i ubuntu2004-uhd4.1-gr3.9.ndz -t node8-7 }}} 1. Turn all the required resources on and check the status {{{#!shell omf tell -a on -t node21-1,node8-7 }}} {{{#!shell omf tell -a on -t [23,1..8] }}} {{{#!shell omf stat -t all }}} 1. {{{ssh}}} to the server and ({{{node8-7}}}) from two terminals, use option -Y for using GUI. {{{#!shell [Terminal 1] ssh -Y root@node21-1, [Terminal 2] ssh -Y root@node8-7 }}} === Experiment Execution === ==== Find and prepare USRPs and the Sounder software ==== * The IP addresses for Ethernet Port 1(10G) on {{{node23-1}}} to {{{node23-8}}} were hard-coded to {{{10.10.23.1}}} to {{{10.10.23.8}}} respectively. To access them from the server {{{node21-1}}}, no configure of the network interface is needed, however, for better performance, we suggest the following operations: {{{#!shell root@node21-1:~# ifconfig CTRL mtu 9000 up root@node21-1:~# sudo sysctl -w net.core.wmem_max=24862979 net.core.wmem_max = 24862979 root@node21-1:~# sudo sysctl -w net.core.rmem_max=24862979 net.core.rmem_max = 24862979 root@node21-1:~# ifconfig CTRL CTRL: flags=4163 mtu 9000 inet 10.10.21.1 netmask 255.255.0.0 broadcast 10.10.255.255 inet6 fe80::9a03:9bff:fe3b:81e3 prefixlen 64 scopeid 0x20 ether 98:03:9b:3b:81:e3 txqueuelen 1000 (Ethernet) RX packets 28985875 bytes 107820952173 (107.8 GB) RX errors 121 dropped 0 overruns 0 frame 121 TX packets 12711747 bytes 14132140459 (14.1 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 }}} * Similarly for {{{node8-7}}}, USRP-B210 is connected via a USB-3 port, and no further configuration of the network interface is needed. * Run {{{uhd_find_device}}} to make sure that the USRP-X310s and USRP-B210s can be reached respectively by {{{node21-1}}} and {{{node8-7}}}: {{{#!shell root@node21-1:~# uhd_find_devices --args="addr0=10.10.23.1" [INFO] [UHD] linux; GNU C++ version 9.3.0; Boost_107100; UHD_4.1.0.4-release -------------------------------------------------- -- UHD Device 0 -------------------------------------------------- Device Address: serial: 30A3570 addr: 10.10.23.1 fpga: XG name: Mercury product: X310 type: x300 root@node8-7:~# uhd_find_devices --args="serial=30AD2E0" [INFO] [UHD] linux; GNU C++ version 9.3.0; Boost_107100; UHD_4.1.0.4-release -------------------------------------------------- -- UHD Device 0 -------------------------------------------------- Device Address: serial: 30AD2E0 name: MyB210 product: B210 type: b200 }}} * In the server {{{node21-1}}}, download and build the RENEW Sounder software **on the {{{Pure-UHD-Multi-USRP}}} branch** at [https://github.com/renew-wireless/RENEWLab/ here] and follow the [https://docs.renew-wireless.org/dev-suite/design-flows/cpp/sounder/ instructions] to build it. * In {{{node8-7}}}, download and build the RENEW Sounder software **on the {{{USRP-B210-New-Sync}}} branch** at [https://github.com/renew-wireless/RENEWLab/ here] and follow the [https://docs.renew-wireless.org/dev-suite/design-flows/cpp/sounder/ instructions] to build it. Note that the {{{master}}} branch does not have UHD support and the {{{Pure-UHD-Multi-USRP}}} branch does not support USRP-B210. * Include in {{{iles/special_conf/usrp_16qam.json}}} the IP address {{{10.10.23.1}}} to {{{10.10.23.8}}} under {{{BaseStations}}} as the base station (BS); * Similarly, set {{{30AD2E0}}} under {{{Clients}}} as the user === Execution === ==== Run the experiment ==== * A file needed to be generated first as: {{{#!shell root@node8-7:~/RENEWLab/CC/Sounder# ./build/sounder --conf files/special_conf/usrp-16QAM.json --gen_data_bits ... ... INFOR: Allocating 1 cores to receive threads ... INFOR: Allocating 1 cores to record threads ... INFOR: Allocating 1 cores to read threads ... INFOR: Allocating 1 cores to client threads ... Config: 1 BS, 1 BS radios (total), 1 UE antennas, 1 pilot symbols per frame, 1 uplink data symbols per frame, 0 downlink data symbols per frame, 64 OFDM subcarriers (52 data subcarriers), modulation 16QAM, frame time 18360.000 usec Thread Config: 1 BS receive threads, 1 Client receive threads, 1 recording threads, 1 reading thread Saving UL data bits for radio 0 to logs/ul_data_b_16QAM_52_64_10_1_1_A_0.bin Saving UL frequency-domain data for radio 0 to logs/ul_data_f_16QAM_52_64_10_1_1_A_0.bin Saving UL time-domain data for radio 0 to logs/ul_data_t_16QAM_52_64_10_1_1_A_0.bin }}} * In order to have the correct Error Vector Magnitude (EVM) and Symbol Error Rate(SER) calculated in post-processing, the exact binary file needs to be used in both the Client and Base Station terminals: {{{#!shell root@node21-1:~# scp root@node8-7:~/RENEWLab/CC/Sounder/logs/ul_data_f_16QAM_52_64_10_1_1_A_0.bin /root/RENEWLab/CC/Sounder/logs }}} * In the USRP-B210 {{{node8-7}}} terminal [Terminal 1], start the client: {{{#!shell root@node8-7:~/RENEWLab/CC/Sounder# ./build/sounder --conf files/special_conf/usrp-16QAM.json --client_only ... ... INFOR: ClientRadioSetUHD done! INFOR: Successfully pinned main scheduler thread to core 0finish start client threads INFOR: Launching reader task thread with id: 1 and core 1 INFOR: Pinning reading thread 1 to core 1 Opening time-domain data for radio 0 to logs/ul_data_t_16QAM_52_64_10_1_1_A_0.bin INFOR: Pinning client synctxrx thread 0 to core 2 INFOR: Scheduling TX: 2 Frames (48.576000 ms) in the future! INFOR: Beacon detected at Time 197069085, sync_index: 106001 Client 0 Estimated CFO (Hz): -213.117 INFOR: Start main client txrx loop... tid=0 Using resync period of 82 }}} * In the server {{{node21-1}}} [Terminal 2], start the BS: {{{#!shell root@node21-1:~/RENEWLab/CC/Sounder# ./build/sounder --conf files/special_conf/usrp-16QAM.json --bs_only ... ... INFOR: Successfully pinned main scheduler thread to core 073:082345 INFOR: Creating recorder thread: 0, with antennas 0:7 total 8 INFOR: Creating output HD5F file: logs/trace-uplink-2022-7-8-7-43-59_1_8x1_0_7.hdf5 INFOR: Launching recorder task thread with id: 0 and core 1 INFOR: Pinning rx thread 0 to core 2 INFOR: Pinning recording thread 0 to core 1 INFOR: Recv Thread 0: waiting for release INFOR: Recording thread 0 has 8 antennas starting at 0 num channels are: 8 INFOR: Receiver thread 0 has 1 radios INFOR: Sync BS host and FPGA timestamp for thread 0 INFOR: Start BS main recv loop in thread 0 INFOR: Saving HD5F: 2000 frames saved on CPU 1 ... ... }}} ==== Analyze the results ==== * Since we run Client and Base Stations in separate terminals, a minor modification in {{{hdf5_lib.py}}} is needed to specify the binary reference in the post-processing script: replace line 916 {{{tx_file_names = metadata['TX_FD_DATA_FILENAMES'].astype(str)}}} with {{{manual_file = ['ul_data_f_16QAM_52_64_10_1_1_A_0.bin']; manual_file = np.array(manual_file); tx_file_names = manual_file;}}} * Once the hdf5 file is recorded (in this case, {{{logs/trace-uplink-2022-7-8-7-43-59_1_8x1_0_7.hdf5}}}), follow the **Analyze the HDF5 dataset** step [https://docs.renew-wireless.org/dev-suite/design-flows/cpp/sounder/ here] to analyze the results. For example, we can show the pilot and uplink IQ waveforms, Uplink User Constealltion along with its Error Vector Magnitude(EVM) and Symbol Error Rate(SER) values (in this case: EVM is 0.88%; SER is 1.45%]): {{{#!shell root@node21-1:~/RENEWLab/PYTHON/IrisUtils# python3 plot_hdf5.py ../../CC/Sounder/logs/trace-uplink-2022-7-8-7-43-59_1_8x1_0_7.hdf5 --ref-frame=250 --signal-offset=1775 --demodulate zf }}} where {{{--ref-frame=250}}} represents the reference frame to look at, and {{{--signal-offset=1775}}} represents the signal offset where this value might be different under different senerios. || [[Image(pilot_1.png, 450px)]] || [[Image(uplink_1.png, 450px)]] || [[Image(constellation_1.png, 450px)]]