Here is a patch that allows a user to define when the stream start command is issued. I use this to precisely time the beginning of the stream. The current implementation issues the stream start command 0.1 seconds after start() is called, which is not that deterministic.
I'm not sure this is optimal, but here is how I use it in python: t = time.time() while t < op.starttime - 3: t = time.time() time.sleep(0.1) ## Latch devices onto PPS, reset clock to 0.0. This takes two seconds. self.uhd_usrp_source_0.set_time_unknown_pps(uhd.time_spec(0.0)) ## Tell the uhd block to issue stream command 1 second after receiving PPS self.uhd_usrp_source_0.set_stream_start_time(1.0) Sorry, I messed up a bit with the patch, so there are a few unnecessary diffs. juha
diff --git a/gr-uhd/include/gr_uhd_usrp_source.h b/gr-uhd/include/gr_uhd_usrp_source.h index 36331f7..77c03ac 100644 --- a/gr-uhd/include/gr_uhd_usrp_source.h +++ b/gr-uhd/include/gr_uhd_usrp_source.h @@ -259,6 +259,11 @@ public: virtual void set_time_unknown_pps(const uhd::time_spec_t &time_spec) = 0; /*! + * \param t start streaming at this time (mboard time). + */ + virtual void set_stream_start_time(double t) = 0; + + /*! * Get access to the underlying uhd dboard iface object. * \return the dboard_iface object */ diff --git a/gr-uhd/lib/gr_uhd_usrp_source.cc b/gr-uhd/lib/gr_uhd_usrp_source.cc index 9983489..89fd0be 100644 --- a/gr-uhd/lib/gr_uhd_usrp_source.cc +++ b/gr-uhd/lib/gr_uhd_usrp_source.cc @@ -43,7 +44,8 @@ public: _type(io_type), _nchan(num_channels), _stream_now(_nchan == 1), - _tmp_buffs(_nchan) + _tmp_buffs(_nchan), + _stream_start_time(0.0) { _dev = uhd::usrp::multi_usrp::make(device_addr); } @@ -166,6 +168,10 @@ public: return _dev->set_time_unknown_pps(time_spec); } + void set_stream_start_time(double t){ + _stream_start_time = t; + } + uhd::usrp::dboard_iface::sptr get_dboard_iface(size_t chan){ return _dev->get_rx_dboard_iface(chan); } @@ -209,22 +216,25 @@ public: for (size_t i = 0; i < _nchan; i++){ _tmp_buffs[i] = static_cast<char *>(output_items[i]) + num_samps*_type.size; } - + //receive all available packets without timeout num_samps += _dev->get_device()->recv( _tmp_buffs, noutput_items, _metadata, _type, uhd::device::RECV_MODE_FULL_BUFF, 0.0 ); - + return num_samps; } bool start(void){ //setup a stream command that starts streaming slightly in the future - static const double reasonable_delay = 0.1; //order of magnitude over RTT + static const double reasonable_delay = 0.1; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); stream_cmd.stream_now = _stream_now; - stream_cmd.time_spec = get_time_now() + uhd::time_spec_t(reasonable_delay); + if(_stream_start_time == 0.0) + stream_cmd.time_spec = get_time_now() + uhd::time_spec_t(reasonable_delay); + else + stream_cmd.time_spec = uhd::time_spec_t(_stream_start_time); _dev->issue_stream_cmd(stream_cmd); return true; } @@ -241,6 +251,7 @@ private: bool _stream_now; gr_vector_void_star _tmp_buffs; uhd::rx_metadata_t _metadata; + double _stream_start_time; };
_______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org https://lists.gnu.org/mailman/listinfo/discuss-gnuradio