Synchronizing USRP source blocks - multiple B2xx devices

1.1k Views Asked by At

I am trying to create a synchronized usrp source block in gnu radio consisting of multiple B210 USRP devices. Lang: C++.

From what I have found I need to:

  • Instantiate multiple multi_usrp_sptr as each B210 requires one and multiple B210 devices cannot be addressed by using single sptr
  • Use external frequency and PPS sources - an option that can be selected from block or set programmatically
  • Synchronize re/tuning to achieve repeatable phase offset between nodes - this can be achieved using timed commands API https://kb.ettus.com/Synchronizing_USRP_Events_Using_Timed_Commands_in_UHD
  • Synchronize sample streams using time_spec property issue_stream cmd

The problem is how should I insert these timed commands and set time_spec of stream in GNU radio block or gr-uhd libs?

I looked into the gr-uhd folder where the sink/source code resided and found functions that could be altered. Unfortunately I don't know how to copy or export this library to do these modifications and later compile to insert my custom blocks to GNU Radio, because gr-uhd seems to be built in and compiled at GR installation. I attempted coping and then making the lib but that's not the way - it didn't succeed. Should I add my own source block via gr_modtool and insert only the commands I need? Compatibility with uhd and its functions apart from just adding a few lines would be advantageous not to write the source from scratch.

Please advise

Edit
Experimental flowchart, based on Marcus Müller suggestion:
Experimental usrp synchronization flow

2

There are 2 best solutions below

1
On

The problem is how should I insert these timed commands and set time_spec of stream in GNU radio block or gr-uhd libs?

For a USRP sink: add tags containing dictionaries with the correct command times to the streams. The GNU Radio API docs have information on how these dictionaries need to look like. The time field is what you need to set with an appropriate value.

For a USRP source: Use the set_start_time on the uhd_usrp_source block; use the same dictionaries described above to issue commands like tuning, gain setting at a coordinated time.

0
On

I was trying to find a proper way of synchronizing the USRPs via tags. There are a few issues I came across in this approach:

  1. Timed commands require the knowledge of the current moment in time, which is done via usrp.get_time_now(), even though I would request the USRP to give the time through tags I would have to somehow extract it from the output. (make some kind of loop and proper triggering) (source: https://kb.ettus.com/Synchronizing_USRP_Events_Using_Timed_Commands_in_UHD) or maybe plan everything not in a relative way - using absolute values instead of offsets. I have seen an approach to regularly reset the sense of time each PPS (set it to 0.0) and maybe then setting time of commands within range of 0.0-1.0 would be acceptable. Then the loop for reading and inserting time into commands would also be redundant.
  2. I didn't found a way to create dicts in GR via blocks to make the solution scalable (without writing a few lines of code in textbox) or writing OOT block
  3. In the end there is so little information to tell what kind of solution is most appropriate (PDU, events, are tags still relevant in GR ?), and the docs are so very scarce, that after some mailing I decided to add a simple class that inherits from the main top_bock.py and after instantiation of top_block it calls a few functions to synchronize the devices. This kind of solution is not the most flexible one, and the parent class top_block.py has to be called through the inheriting one, but it enables an easy programming interface.

Soon I will add an example of the code used in inheriting class just in case.

If there is any more neat, dynamic or scalable solution please let me know or point me to sources.