USRP Hardware Driver (UHD) Support¶
AirStack allows for the AIR-T to run UHD applications via a translation layer known as SoapyUHD. As a result, applications previously developed for the USRP family of devices can be run on the AIR-T, but may require some minor modifications.
It should be noted that compatibility between UHD and the AIR-T is a "moving target" as various software components are always being updated. As a result, if you are experiencing issues with UHD, please reach out to us via our support channels and we will be happy to assist you.
Installation¶
It is recommended to install UHD and SoapyUHD through conda
if possible. This will "sandbox" the UHD installation to a specific conda
environment and not affect the installation of SoapySDR and other critical components of AirStack.
A good starting point is the GNU Radio Tutorial as this sets up a conda
environment with just about everything needed to run UHD applications (including GNU Radio). However, there is one missing component (SoapyUHD) that does not get installed via this tutorial. SoapyUHD is absolutely critical for our purposes here, since it contains the software that translates between the UHD and SoapySDR APIs and allows for UHD to treat the AIR-T as a UHD device. As a result, we must install it prior to running any UHD applications on the AIR-T.
If you are following the GNU Radio Tutorial and/or already have a conda
environment created, you can run conda install soapysdr-module-uhd
to install SoapyUHD. Alternatively, if you are starting from scratch and creating a new conda
environment, simply include soapysdr-module-uhd
as a dependency when creating/editing the YAML file.
To verify that you have all the correct components installed, simply run uhd_find_devices
and you should see the AIR-T report itself as a UHD device. From there, you can also run uhd_fft
to run a example UHD application.
GNU Radio Blocks¶
Many users who are interfacing to SDR hardware via UHD are doing so through the UHD source and sink blocks in GNU Radio. For these users (i.e., those who have existing GNU Radio flowgraphs/applications using the UHD blocks), we strongly recommend simply replacing the source/sink blocks in your flowgraph with the appropriate SoapyAIRT blocks. This offers a number of advantages; namely it avoids layers of software/complexity and allows for the application to communicate with the hardware as directly as possible. That said, we also recognize that the UHD blocks are more mature and can offer more advanced features than the comparable gr-soapy
blocks. That said, there are a few known issues with using the UHD blocks. We discuss these (and their associated workarounds) in the sections to follow.
Known Issue: UHD Source Multi Channel Sync¶
The UHD source block in GNU Radio will attempt to always synchronize channels in a multiple channel stream via a timed command. That is, signal reception is told to start some time in the future in order to ensure all channels start reception at the same time and are therefore synchronized to one another.
When working with the UHD source block, you may encounter a warning or error message from the AIR-T describing that all channels did not start signal reception at the same time. If you do not require RX channels to be synchronized, you can ignore these messages. If you do require synchronized channels, there is a workaround you can employ.
The root cause of the issue is that the start time inside the command to start signal reception is 100 milliseconds in the future from whatever the hardware is reporting "now" to be. This is a hardcoded value in the block itself. Based on the complexity of your flowgraph, this may or may not be sufficient time for the command to be issued to the hardware. However, via a call to the block's Python API we can edit this time parameter accordingly. The example code below shows how to set the start time to be 1.5 seconds in the future, which is plenty of time for the AIR-T.
time_now = self.uhd_usrp_source_0.get_time_now()
start_time = time_now + 1.5
self.uhd_usrp_source_0.set_start_time(start_time)
Unfortunately, this parameter cannot be readily set through GNU Radio Companion (GRC). As a result, the above code must be manually added to the Python script generated by GRC each time the script is generated. We recommend placing these lines of code in the "top block's" constructor, above where all the connections between blocks are made.