Added support to multiband frontends (UHD multiband) in UHD signal

source. Still to do modifications in flowgraph to connect the signal
conditioners and the next chained blocks..
This commit is contained in:
Javier 2015-02-18 18:46:00 +01:00
parent d275a3612f
commit 8606191311
6 changed files with 606 additions and 140 deletions

View File

@ -0,0 +1,399 @@
; Default configuration file
; You can define your own receiver and invoke it by doing
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
;
[GNSS-SDR]
;######### GLOBAL OPTIONS ##################
;internal_fs_hz: Internal signal sampling frequency after the signal conditioning stage [Hz].
GNSS-SDR.internal_fs_hz=4000000
;######### CONTROL_THREAD CONFIG ############
ControlThread.wait_for_flowgraph=false
;######### SUPL RRLP GPS assistance configuration #####
GNSS-SDR.SUPL_gps_enabled=false
GNSS-SDR.SUPL_read_gps_assistance_xml=true
GNSS-SDR.SUPL_gps_ephemeris_server=supl.nokia.com
GNSS-SDR.SUPL_gps_ephemeris_port=7275
GNSS-SDR.SUPL_gps_acquisition_server=supl.google.com
GNSS-SDR.SUPL_gps_acquisition_port=7275
GNSS-SDR.SUPL_MCC=244
GNSS-SDR.SUPL_MNS=5
GNSS-SDR.SUPL_LAC=0x59e2
GNSS-SDR.SUPL_CI=0x31b0
;######### SIGNAL_SOURCE CONFIG ############
;#implementation: Use [File_Signal_Source] or [UHD_Signal_Source] or [GN3S_Signal_Source] (experimental)
SignalSource.implementation=UHD_Signal_Source
;#When left empty, the device discovery routines will search all vailable transports on the system (ethernet, usb...)
SignalSource.device_address=192.168.40.2
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
SignalSource.item_type=gr_complex
;#RF_channels: Number of RF channels present in the frontend device (i.e. USRP with two frontends)
SignalSource.RF_channels=2
;#sampling_frequency: Original Signal sampling frequency in [Hz]
SignalSource.sampling_frequency=4000000
;#subdevice: UHD subdevice specification (for USRP dual frontend use A:0 or B:0 or A:0 B:0)
SignalSource.subdevice=A:0 B:0
;######### RF Channels specific settings ######
;## RF CHANNEL 0 ##
;#freq: RF front-end center frequency in [Hz]
SignalSource.freq0=1575420000
;#gain: Front-end Gain in [dB]
SignalSource.gain0=40
;#samples: Number of samples to be processed. Notice that 0 indicates no limit
SignalSource.samples0=0
;#dump: Dump the Signal source RF channel data to a file. Disable this option in this version
SignalSource.dump0=false
SignalSource.dump_filename0=../data/signal_source0.dat
;## RF CHANNEL 1 ##
;#freq: RF front-end center frequency in [Hz]
SignalSource.freq1=1575420000
;#gain: Front-end Gain in [dB]
SignalSource.gain1=40
;#samples: Number of samples to be processed. Notice that 0 indicates no limit
SignalSource.samples1=0
;#dump: Dump the Signal source RF channel data to a file. Disable this option in this version
SignalSource.dump1=false
SignalSource.dump_filename1=../data/signal_source1.dat
;######### SIGNAL_CONDITIONER CONFIG ############
;## It holds blocks to change data type, filter and resample input data.
;#implementation: Use [Pass_Through] or [Signal_Conditioner]
;#[Pass_Through] disables this block and the [DataTypeAdapter], [InputFilter] and [Resampler] blocks
;#[Signal_Conditioner] enables this block. Then you have to configure [DataTypeAdapter], [InputFilter] and [Resampler] blocks
;SignalConditioner.implementation=Signal_Conditioner
SignalConditioner.implementation=Pass_Through
;######### DATA_TYPE_ADAPTER CONFIG ############
;## Changes the type of input data. Please disable it in this version.
;#implementation: [Pass_Through] disables this block
DataTypeAdapter.implementation=Pass_Through
;######### INPUT_FILTER CONFIG ############
;## Filter the input data. Can be combined with frequency translation for IF signals
;#implementation: Use [Pass_Through] or [Fir_Filter] or [Freq_Xlating_Fir_Filter]
;#[Pass_Through] disables this block
;#[Fir_Filter] enables a FIR Filter
;#[Freq_Xlating_Fir_Filter] enables FIR filter and a composite frequency translation that shifts IF down to zero Hz.
;InputFilter.implementation=Fir_Filter
;InputFilter.implementation=Freq_Xlating_Fir_Filter
InputFilter.implementation=Pass_Through
;#dump: Dump the filtered data to a file.
InputFilter.dump=false
;#dump_filename: Log path and filename.
InputFilter.dump_filename=../data/input_filter.dat
;#The following options are used in the filter design of Fir_Filter and Freq_Xlating_Fir_Filter implementation.
;#These options are based on parameters of gnuradio's function: gr_remez.
;#These function calculates the optimal (in the Chebyshev/minimax sense) FIR filter inpulse reponse given a set of band edges, the desired reponse on those bands, and the weight given to the error in those bands.
;#input_item_type: Type and resolution for input signal samples. Use only gr_complex in this version.
InputFilter.input_item_type=gr_complex
;#outut_item_type: Type and resolution for output filtered signal samples. Use only gr_complex in this version.
InputFilter.output_item_type=gr_complex
;#taps_item_type: Type and resolution for the taps of the filter. Use only float in this version.
InputFilter.taps_item_type=float
;#number_of_taps: Number of taps in the filter. Increasing this parameter increases the processing time
InputFilter.number_of_taps=5
;#number_of _bands: Number of frequency bands in the filter.
InputFilter.number_of_bands=2
;#bands: frequency at the band edges [ b1 e1 b2 e2 b3 e3 ...].
;#Frequency is in the range [0, 1], with 1 being the Nyquist frequency (Fs/2)
;#The number of band_begin and band_end elements must match the number of bands
InputFilter.band1_begin=0.0
InputFilter.band1_end=0.45
InputFilter.band2_begin=0.55
InputFilter.band2_end=1.0
;#ampl: desired amplitude at the band edges [ a(b1) a(e1) a(b2) a(e2) ...].
;#The number of ampl_begin and ampl_end elements must match the number of bands
InputFilter.ampl1_begin=1.0
InputFilter.ampl1_end=1.0
InputFilter.ampl2_begin=0.0
InputFilter.ampl2_end=0.0
;#band_error: weighting applied to each band (usually 1).
;#The number of band_error elements must match the number of bands
InputFilter.band1_error=1.0
InputFilter.band2_error=1.0
;#filter_type: one of "bandpass", "hilbert" or "differentiator"
InputFilter.filter_type=bandpass
;#grid_density: determines how accurately the filter will be constructed.
;The minimum value is 16; higher values are slower to compute the filter.
InputFilter.grid_density=16
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
InputFilter.sampling_frequency=4000000
InputFilter.IF=0
;######### RESAMPLER CONFIG ############
;## Resamples the input data.
;#implementation: Use [Pass_Through] or [Direct_Resampler]
;#[Pass_Through] disables this block
;#[Direct_Resampler] enables a resampler that implements a nearest neigbourhood interpolation
;Resampler.implementation=Direct_Resampler
Resampler.implementation=Pass_Through
;#dump: Dump the resampled data to a file.
Resampler.dump=false
;#dump_filename: Log path and filename.
Resampler.dump_filename=../data/resampler.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
Resampler.item_type=gr_complex
;#sample_freq_in: the sample frequency of the input signal
Resampler.sample_freq_in=4000000
;#sample_freq_out: the desired sample frequency of the output signal
Resampler.sample_freq_out=4000000
;######### CHANNELS GLOBAL CONFIG ############
;#count: Number of available GPS satellite channels.
Channels_GPS.count=8
;#count: Number of available Galileo satellite channels.
Channels_Galileo.count=0
;#in_acquisition: Number of channels simultaneously acquiring for the whole receiver
Channels.in_acquisition=1
;#system: GPS, GLONASS, GALILEO, SBAS or COMPASS
;#if the option is disabled by default is assigned GPS
Channel.system=GPS
;#signal:
;# "1C" GPS L1 C/A
;# "1P" GPS L1 P
;# "1W" GPS L1 Z-tracking and similar (AS on)
;# "1Y" GPS L1 Y
;# "1M" GPS L1 M
;# "1N" GPS L1 codeless
;# "2C" GPS L2 C/A
;# "2D" GPS L2 L1(C/A)+(P2-P1) semi-codeless
;# "2S" GPS L2 L2C (M)
;# "2L" GPS L2 L2C (L)
;# "2X" GPS L2 L2C (M+L)
;# "2P" GPS L2 P
;# "2W" GPS L2 Z-tracking and similar (AS on)
;# "2Y" GPS L2 Y
;# "2M" GPS GPS L2 M
;# "2N" GPS L2 codeless
;# "5I" GPS L5 I
;# "5Q" GPS L5 Q
;# "5X" GPS L5 I+Q
;# "1C" GLONASS G1 C/A
;# "1P" GLONASS G1 P
;# "2C" GLONASS G2 C/A (Glonass M)
;# "2P" GLONASS G2 P
;# "1A" GALILEO E1 A (PRS)
;# "1B" GALILEO E1 B (I/NAV OS/CS/SoL)
;# "1C" GALILEO E1 C (no data)
;# "1X" GALILEO E1 B+C
;# "1Z" GALILEO E1 A+B+C
;# "5I" GALILEO E5a I (F/NAV OS)
;# "5Q" GALILEO E5a Q (no data)
;# "5X" GALILEO E5a I+Q
;# "7I" GALILEO E5b I
;# "7Q" GALILEO E5b Q
;# "7X" GALILEO E5b I+Q
;# "8I" GALILEO E5 I
;# "8Q" GALILEO E5 Q
;# "8X" GALILEO E5 I+Q
;# "6A" GALILEO E6 A
;# "6B" GALILEO E6 B
;# "6C" GALILEO E6 C
;# "6X" GALILEO E6 B+C
;# "6Z" GALILEO E6 A+B+C
;# "1C" SBAS L1 C/A
;# "5I" SBAS L5 I
;# "5Q" SBAS L5 Q
;# "5X" SBAS L5 I+Q
;# "2I" COMPASS E2 I
;# "2Q" COMPASS E2 Q
;# "2X" COMPASS E2 IQ
;# "7I" COMPASS E5b I
;# "7Q" COMPASS E5b Q
;# "7X" COMPASS E5b IQ
;# "6I" COMPASS E6 I
;# "6Q" COMPASS E6 Q
;# "6X" COMPASS E6 IQ
;#if the option is disabled by default is assigned "1C" GPS L1 C/A
Channel.signal=1C
;######### SPECIFIC CHANNELS CONFIG ######
;#The following options are specific to each channel and overwrite the generic options
;######### CHANNEL 0 CONFIG ############
Channel0.system=GPS
Channel0.signal=1C
;#satellite: Satellite PRN ID for this channel. Disable this option to random search
Channel0.satellite=11
;######### CHANNEL 1 CONFIG ############
Channel1.system=GPS
Channel1.signal=1C
Channel1.satellite=18
;######### ACQUISITION GLOBAL CONFIG ############
;#dump: Enable or disable the acquisition internal data file logging [true] or [false]
Acquisition_GPS.dump=false
;#filename: Log path and filename
Acquisition_GPS.dump_filename=./acq_dump.dat
;#item_type: Type and resolution for each of the signal samples. Use only gr_complex in this version.
Acquisition_GPS.item_type=gr_complex
;#if: Signal intermediate frequency in [Hz]
Acquisition_GPS.if=0
;#sampled_ms: Signal block duration for the acquisition signal detection [ms]
Acquisition_GPS.coherent_integration_time_ms=1
;#implementation: Acquisition algorithm selection for this channel: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
Acquisition_GPS.implementation=GPS_L1_CA_PCPS_Acquisition
;#threshold: Acquisition threshold. It will be ignored if pfa is defined.
Acquisition_GPS.threshold=0.02
;#pfa: Acquisition false alarm probability. This option overrides the threshold option. Only use with implementations: [GPS_L1_CA_PCPS_Acquisition] or [Galileo_E1_PCPS_Ambiguous_Acquisition]
;Acquisition_GPS.pfa=0.0001
;#doppler_max: Maximum expected Doppler shift [Hz]
Acquisition_GPS.doppler_max=8000
;#doppler_max: Doppler step in the grid search [Hz]
Acquisition_GPS.doppler_step=500
;#bit_transition_flag: Enable or disable a strategy to deal with bit transitions in GPS signals: process two dwells and take
maximum test statistics. Only use with implementation: [GPS_L1_CA_PCPS_Acquisition] (should not be used for Galileo_E1_PCPS_Ambiguous_Acquisition])
Acquisition_GPS.bit_transition_flag=false
;#max_dwells: Maximum number of consecutive dwells to be processed. It will be ignored if bit_transition_flag=true
Acquisition_GPS.max_dwells=1
;######### ACQUISITION CHANNELS CONFIG ######
;#The following options are specific to each channel and overwrite the generic options
;######### TRACKING GLOBAL CONFIG ############
;#implementation: Selected tracking algorithm: [GPS_L1_CA_DLL_PLL_Tracking] or [GPS_L1_CA_DLL_FLL_PLL_Tracking]
Tracking_GPS.implementation=GPS_L1_CA_DLL_PLL_Optim_Tracking
;#item_type: Type and resolution for each of the signal samples. Use only [gr_complex] in this version.
Tracking_GPS.item_type=gr_complex
;#sampling_frequency: Signal Intermediate Frequency in [Hz]
Tracking_GPS.if=0
;#dump: Enable or disable the Tracking internal binary data file logging [true] or [false]
Tracking_GPS.dump=false
;#dump_filename: Log path and filename. Notice that the tracking channel will add "x.dat" where x is the channel number.
Tracking_GPS.dump_filename=./tracking_ch_
;#pll_bw_hz: PLL loop filter bandwidth [Hz]
Tracking_GPS.pll_bw_hz=50.0;
;#dll_bw_hz: DLL loop filter bandwidth [Hz]
Tracking_GPS.dll_bw_hz=2.0;
;#fll_bw_hz: FLL loop filter bandwidth [Hz]
Tracking_GPS.fll_bw_hz=10.0;
;#order: PLL/DLL loop filter order [2] or [3]
Tracking_GPS.order=3;
;#early_late_space_chips: correlator early-late space [chips]. Use [0.5]
Tracking_GPS.early_late_space_chips=0.5;
;######### TELEMETRY DECODER GPS CONFIG ############
;#implementation: Use [GPS_L1_CA_Telemetry_Decoder] for GPS L1 C/A
TelemetryDecoder_GPS.implementation=GPS_L1_CA_Telemetry_Decoder
TelemetryDecoder_GPS.dump=false
;#decimation factor
TelemetryDecoder_GPS.decimation_factor=1;
;######### OBSERVABLES CONFIG ############
;#implementation: Use [GPS_L1_CA_Observables] for GPS L1 C/A.
Observables.implementation=GPS_L1_CA_Observables
;#dump: Enable or disable the Observables internal binary data file logging [true] or [false]
Observables.dump=false
;#dump_filename: Log path and filename.
Observables.dump_filename=./observables.dat
;######### PVT CONFIG ############
;#implementation: Position Velocity and Time (PVT) implementation algorithm: Use [GPS_L1_CA_PVT] in this version.
PVT.implementation=GPS_L1_CA_PVT
;#averaging_depth: Number of PVT observations in the moving average algorithm
PVT.averaging_depth=10
;#flag_average: Enables the PVT averaging between output intervals (arithmetic mean) [true] or [false]
PVT.flag_averaging=true
;#output_rate_ms: Period between two PVT outputs. Notice that the minimum period is equal to the tracking integration time (for GPS CA L1 is 1ms) [ms]
PVT.output_rate_ms=100
;#display_rate_ms: Position console print (std::out) interval [ms]. Notice that output_rate_ms<=display_rate_ms.
PVT.display_rate_ms=500
;# RINEX, KML, and NMEA output configuration
;#dump_filename: Log path and filename without extension. Notice that PVT will add ".dat" to the binary dump and ".kml" to GoogleEarth dump.
PVT.dump_filename=./PVT
;#nmea_dump_filename: NMEA log path and filename
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
;#flag_nmea_tty_port: Enable or disable the NMEA log to a serial TTY port (Can be used with real hardware or virtual one)
PVT.flag_nmea_tty_port=false;
;#nmea_dump_devname: serial device descriptor for NMEA logging
PVT.nmea_dump_devname=/dev/pts/4
;#dump: Enable or disable the PVT internal binary data file logging [true] or [false]
PVT.dump=false
;######### OUTPUT_FILTER CONFIG ############
;# Receiver output filter: Leave this block disabled in this version
OutputFilter.implementation=Null_Sink_Output_Filter
OutputFilter.filename=data/gnss-sdr.dat
OutputFilter.item_type=gr_complex

View File

@ -50,28 +50,51 @@ UhdSignalSource::UhdSignalSource(ConfigurationInterface* configuration,
std::string empty = "";
std::string default_dump_file = "./data/signal_source.dat";
std::string default_item_type = "cshort";
samples_ = configuration->property(role + ".samples", 0);
dump_ = configuration->property(role + ".dump", false);
dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file);
// UHD PARAMETERS
uhd::device_addr_t dev_addr;
device_address_= configuration->property(role + ".device_address", empty);
// When left empty, the device discovery routines will search all
// available transports on the system (ethernet, usb...).
// To narrow down the discovery process to a particular device,
// specify a transport key/value pair specific to your device.
if (empty.compare(device_address_) != 0) // if not empty
{
dev_addr["addr"] = device_address_;
}
subdevice_ = configuration->property(role + ".subdevice", empty);
freq_ = configuration->property(role + ".freq", GPS_L1_FREQ_HZ);
gain_ = configuration->property(role + ".gain", (double)50.0);
sample_rate_ = configuration->property(role + ".sampling_frequency", (double)4.0e6);
IF_bandwidth_hz_ = configuration->property(role + ".IF_bandwidth_hz", sample_rate_/2);
item_type_ = configuration->property(role + ".item_type", default_item_type);
// UHD COMMON PARAMETERS
uhd::device_addr_t dev_addr;
device_address_= configuration->property(role + ".device_address", empty);
// When left empty, the device discovery routines will search all
// available transports on the system (ethernet, usb...).
// To narrow down the discovery process to a particular device,
// specify a transport key/value pair specific to your device.
if (empty.compare(device_address_) != 0) // if not empty
{
dev_addr["addr"] = device_address_;
}
subdevice_=configuration->property(role + ".subdevice", empty);
RF_channels_=configuration->property(role + ".RF_channels", 1);
sample_rate_ = configuration->property(role + ".sampling_frequency", (double)4.0e6);
item_type_ = configuration->property(role + ".item_type", default_item_type);
if (RF_channels_==1)
{
// Single RF channel UHD operation (backward compatible config file format)
samples_.push_back(configuration->property(role + ".samples", 0));
dump_.push_back(configuration->property(role + ".dump", false));
dump_filename_.push_back(configuration->property(role + ".dump_filename", default_dump_file));
freq_.push_back(configuration->property(role + ".freq", GPS_L1_FREQ_HZ));
gain_.push_back(configuration->property(role + ".gain", (double)50.0));
IF_bandwidth_hz_.push_back(configuration->property(role + ".IF_bandwidth_hz", sample_rate_/2));
}else{
// multiple RF channels selected
for (int i=0;i<RF_channels_;i++)
{
// Single RF channel UHD operation (backward compatible config file format)
samples_.push_back(configuration->property(role + ".samples" + boost::lexical_cast<std::string>(i), 0));
dump_.push_back(configuration->property(role + ".dump" + boost::lexical_cast<std::string>(i), false));
dump_filename_.push_back(configuration->property(role + ".dump_filename" + boost::lexical_cast<std::string>(i), default_dump_file));
freq_.push_back(configuration->property(role + ".freq" + boost::lexical_cast<std::string>(i), GPS_L1_FREQ_HZ));
gain_.push_back(configuration->property(role + ".gain" + boost::lexical_cast<std::string>(i), (double)50.0));
IF_bandwidth_hz_.push_back(configuration->property(role + ".IF_bandwidth_hz" + boost::lexical_cast<std::string>(i), sample_rate_/2));
}
}
// 1. Make the uhd driver instance
//uhd_source_= uhd::usrp::multi_usrp::make(dev_addr);
@ -85,25 +108,45 @@ UhdSignalSource::UhdSignalSource(ConfigurationInterface* configuration,
if (item_type_.compare("cbyte") == 0)
{
item_size_ = sizeof(lv_8sc_t);
uhd_source_ = gr::uhd::usrp_source::make(dev_addr, uhd::stream_args_t("sc8"));
uhd_stream_args_=uhd::stream_args_t("sc8");
}
else if (item_type_.compare("cshort") == 0)
{
item_size_ = sizeof(lv_16sc_t);
uhd_source_ = gr::uhd::usrp_source::make(dev_addr, uhd::stream_args_t("sc16"));
uhd_stream_args_=uhd::stream_args_t("sc16");
}
else if (item_type_.compare("gr_complex") == 0)
{
item_size_ = sizeof(gr_complex);
uhd_source_ = gr::uhd::usrp_source::make(dev_addr, uhd::stream_args_t("fc32"));
uhd_stream_args_=uhd::stream_args_t("fc32");
}
else
{
LOG(WARNING) << item_type_ << " unrecognized item type. Using cshort.";
item_size_ = sizeof(lv_16sc_t);
uhd_source_ = gr::uhd::usrp_source::make(dev_addr, uhd::stream_args_t("sc16"));
uhd_stream_args_=uhd::stream_args_t("sc16");
}
// select the number of channels and the subdevice specifications
for (int i=0;i<RF_channels_;i++)
{
uhd_stream_args_.channels.push_back(i);
}
// 1.2 Make the UHD source object
uhd_source_ = gr::uhd::usrp_source::make(dev_addr, uhd_stream_args_);
// Set subdevice specification string for USRP family devices. It is composed of:
// <motherboard slot name>:<daughterboard frontend name>
// For motherboards: All USRP family motherboards have a first slot named A:.
// The USRP1 has two daughterboard subdevice slots, known as A: and B:.
// For daughterboards, see http://files.ettus.com/uhd_docs/manual/html/dboards.html
// "0" is valid for DBSRX, DBSRX2, WBX Series
// Dual channel example: "A:0 B:0"
// TODO: Add support for multiple motherboards (i.e. four channels "A:0 B:0 A:1 B1")
uhd_source_->set_subdev_spec(subdevice_, 0);
// 2.1 set sampling clock reference
// Set the clock source for the usrp device.
// Options: internal, external, or MIMO
@ -116,69 +159,70 @@ UhdSignalSource::UhdSignalSource(ConfigurationInterface* configuration,
std::cout << boost::format("Sampling Rate for the USRP device: %f [sps]...") % (uhd_source_->get_samp_rate()) << std::endl;
LOG(INFO) << boost::format("Sampling Rate for the USRP device: %f [sps]...") % (uhd_source_->get_samp_rate());
// 3. Tune the usrp device to the desired center frequency
uhd_source_->set_center_freq(freq_);
std::cout << boost::format("Actual USRP center freq.: %f [Hz]...") % (uhd_source_->get_center_freq()) << std::endl << std::endl;
LOG(INFO) << boost::format("Actual USRP center freq. set to: %f [Hz]...") % (uhd_source_->get_center_freq());
std::vector<std::string> sensor_names;
// TODO: Assign the remnant IF from the PLL tune error
std::cout << boost::format("PLL Frequency tune error %f [Hz]...") % (uhd_source_->get_center_freq() - freq_) << std::endl;
LOG(INFO) << boost::format("PLL Frequency tune error %f [Hz]...") % (uhd_source_->get_center_freq() - freq_);
for (int i=0;i<RF_channels_;i++)
{
// 3. Tune the usrp device to the desired center frequency
uhd_source_->set_center_freq(freq_.at(i),i);
std::cout << boost::format("Actual USRP center freq.: %f [Hz]...") % (uhd_source_->get_center_freq(i)) << std::endl << std::endl;
LOG(INFO) << boost::format("Actual USRP center freq. set to: %f [Hz]...") % (uhd_source_->get_center_freq(i));
// 4. set the gain for the daughterboard
uhd_source_->set_gain(gain_);
std::cout << boost::format("Actual daughterboard gain set to: %f dB...") % uhd_source_->get_gain() << std::endl;
LOG(INFO) << boost::format("Actual daughterboard gain set to: %f dB...") % uhd_source_->get_gain();
// TODO: Assign the remnant IF from the PLL tune error
std::cout << boost::format("PLL Frequency tune error %f [Hz]...") % (uhd_source_->get_center_freq(i) - freq_.at(i)) << std::endl;
LOG(INFO) << boost::format("PLL Frequency tune error %f [Hz]...") % (uhd_source_->get_center_freq(i) - freq_.at(i));
//5. Set the bandpass filter on the RF frontend
std::cout << boost::format("Setting RF bandpass filter bandwidth to: %f [Hz]...") % IF_bandwidth_hz_ << std::endl;
uhd_source_->set_bandwidth(IF_bandwidth_hz_);
// 4. set the gain for the daughterboard
uhd_source_->set_gain(gain_.at(i),i);
std::cout << boost::format("Actual daughterboard gain set to: %f dB...") % uhd_source_->get_gain(i) << std::endl;
LOG(INFO) << boost::format("Actual daughterboard gain set to: %f dB...") % uhd_source_->get_gain(i);
//set the antenna (optional)
//uhd_source_->set_antenna(ant);
//5. Set the bandpass filter on the RF frontend
std::cout << boost::format("Setting RF bandpass filter bandwidth to: %f [Hz]...") % IF_bandwidth_hz_.at(i) << std::endl;
uhd_source_->set_bandwidth(IF_bandwidth_hz_.at(i),i);
// We should wait? #include <boost/thread.hpp>
// boost::this_thread::sleep(boost::posix_time::seconds(1));
//set the antenna (optional)
//uhd_source_->set_antenna(ant);
// Check out the status of the lo_locked sensor (boolean for LO lock state)
std::vector<std::string> sensor_names;
sensor_names = uhd_source_->get_sensor_names(0);
if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end())
{
uhd::sensor_value_t lo_locked = uhd_source_->get_sensor("lo_locked", 0);
std::cout << boost::format("Check for front-end %s ...") % lo_locked.to_pp_string() << " is ";
if (lo_locked.to_bool() == true)
{
std::cout << "Locked" << std::endl;
}
else
{
std::cout << "UNLOCKED!" <<std::endl;
}
//UHD_ASSERT_THROW(lo_locked.to_bool());
}
// We should wait? #include <boost/thread.hpp>
// boost::this_thread::sleep(boost::posix_time::seconds(1));
// Set subdevice specification string for USRP family devices. It is composed of:
// <motherboard slot name>:<daughterboard frontend name>
// For motherboards: All USRP family motherboards have a first slot named A:.
// The USRP1 has two daughterboard subdevice slots, known as A: and B:.
// For daughterboards, see http://files.ettus.com/uhd_docs/manual/html/dboards.html
// "0" is valid for DBSRX, DBSRX2, WBX Series
uhd_source_->set_subdev_spec(subdevice_, 0);
// Check out the status of the lo_locked sensor (boolean for LO lock state)
sensor_names = uhd_source_->get_sensor_names(i);
if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end())
{
uhd::sensor_value_t lo_locked = uhd_source_->get_sensor("lo_locked", i);
std::cout << boost::format("Check for front-end %s ...") % lo_locked.to_pp_string() << " is ";
if (lo_locked.to_bool() == true)
{
std::cout << "Locked" << std::endl;
}
else
{
std::cout << "UNLOCKED!" <<std::endl;
}
//UHD_ASSERT_THROW(lo_locked.to_bool());
}
}
if (samples_ != 0)
{
LOG(INFO) << "Send STOP signal after " << samples_ << " samples";
valve_ = gnss_sdr_make_valve(item_size_, samples_, queue_);
DLOG(INFO) << "valve(" << valve_->unique_id() << ")";
}
if (dump_)
{
LOG(INFO) << "Dumping output into file " << dump_filename_;
file_sink_ = gr::blocks::file_sink::make(item_size_, dump_filename_.c_str());
DLOG(INFO) << "file_sink(" << file_sink_->unique_id() << ")";
}
for (int i=0;i<RF_channels_;i++)
{
if (samples_.at(i) != 0)
{
LOG(INFO) << "RF_channel "<<i<<" Send STOP signal after " << samples_.at(i) << " samples";
valve_.push_back(gnss_sdr_make_valve(item_size_, samples_.at(i), queue_));
DLOG(INFO) << "valve(" << valve_.at(i)->unique_id() << ")";
}
if (dump_.at(i))
{
LOG(INFO) << "RF_channel "<<i<< "Dumping output into file " << dump_filename_.at(i);
file_sink_.push_back(gr::blocks::file_sink::make(item_size_, dump_filename_.at(i).c_str()));
DLOG(INFO) << "file_sink(" << file_sink_.at(i)->unique_id() << ")";
}
}
}
@ -186,50 +230,56 @@ UhdSignalSource::UhdSignalSource(ConfigurationInterface* configuration,
UhdSignalSource::~UhdSignalSource()
{}
void UhdSignalSource::connect(gr::top_block_sptr top_block)
{
if (samples_ != 0)
{
top_block->connect(uhd_source_, 0, valve_, 0);
DLOG(INFO) << "connected usrp source to valve";
if (dump_)
{
top_block->connect(valve_, 0, file_sink_, 0);
DLOG(INFO) << "connected valve to file sink";
}
}
else
{
if (dump_)
{
top_block->connect(uhd_source_, 0, file_sink_, 0);
DLOG(INFO) << "connected usrp source to file sink";
}
}
for (int i=0;i<RF_channels_;i++)
{
if (samples_.at(i) != 0)
{
top_block->connect(uhd_source_, i, valve_.at(i), 0);
DLOG(INFO) << "connected usrp source to valve RF Channel "<< i;
if (dump_.at(i))
{
top_block->connect(valve_.at(i), 0, file_sink_.at(i), 0);
DLOG(INFO) << "connected valve to file sink RF Channel "<< i;
}
}
else
{
if (dump_.at(i))
{
top_block->connect(uhd_source_, i, file_sink_.at(i), 0);
DLOG(INFO) << "connected usrp source to file sink RF Channel "<< i;
}
}
}
}
void UhdSignalSource::disconnect(gr::top_block_sptr top_block)
{
if (samples_ != 0)
{
top_block->disconnect(uhd_source_, 0, valve_, 0);
LOG(INFO) << "UHD source disconnected";
if (dump_)
{
top_block->disconnect(valve_, 0, file_sink_, 0);
}
}
else
{
if (dump_)
{
top_block->disconnect(uhd_source_, 0, file_sink_, 0);
}
}
for (int i=0;i<RF_channels_;i++)
{
if (samples_.at(i) != 0)
{
top_block->disconnect(uhd_source_, i, valve_.at(i), 0);
LOG(INFO) << "UHD source disconnected";
if (dump_.at(i))
{
top_block->disconnect(valve_.at(i), 0, file_sink_.at(i), 0);
}
}
else
{
if (dump_.at(i))
{
top_block->disconnect(uhd_source_, i, file_sink_.at(i), 0);
}
}
}
}
@ -243,11 +293,11 @@ gr::basic_block_sptr UhdSignalSource::get_left_block()
gr::basic_block_sptr UhdSignalSource::get_right_block()
gr::basic_block_sptr UhdSignalSource::get_right_block(int RF_channel)
{
if (samples_ != 0)
if (samples_.at(RF_channel) != 0)
{
return valve_;
return valve_.at(RF_channel);
}
else
{

View File

@ -75,35 +75,35 @@ public:
void connect(gr::top_block_sptr top_block);
void disconnect(gr::top_block_sptr top_block);
gr::basic_block_sptr get_left_block();
gr::basic_block_sptr get_right_block();
gr::basic_block_sptr get_right_block(int RF_channel);
private:
std::string role_;
// UHD SETTINGS
std::string device_address_;
std::string subdevice_;
double sample_rate_;
unsigned int in_stream_;
unsigned int out_stream_;
double freq_;
double gain_;
double IF_bandwidth_hz_;
std::string item_type_;
size_t item_size_;
long samples_;
bool dump_;
std::string dump_filename_;
//boost::shared_ptr<uhd_usrp_source> uhd_source_;
gr::uhd::usrp_source::sptr uhd_source_;
boost::shared_ptr<gr::block> valve_;
//gr_block_sptr file_sink_;
gr::blocks::file_sink::sptr file_sink_;
// UHD SETTINGS
uhd::stream_args_t uhd_stream_args_;
std::string device_address_;
double sample_rate_;
int RF_channels_;
std::string item_type_;
size_t item_size_;
std::string subdevice_;
std::vector<double> freq_;
std::vector<double> gain_;
std::vector<double> IF_bandwidth_hz_;
std::vector<long> samples_;
std::vector<bool> dump_;
std::vector<std::string> dump_filename_;
std::vector<boost::shared_ptr<gr::block>> valve_;
std::vector<gr::blocks::file_sink::sptr> file_sink_;
boost::shared_ptr<gr::msg_queue> queue_;
};

View File

@ -58,8 +58,25 @@ public:
virtual size_t item_size() = 0;
virtual void connect(gr::top_block_sptr top_block) = 0;
virtual void disconnect(gr::top_block_sptr top_block) = 0;
virtual gr::basic_block_sptr get_left_block() = 0;
virtual gr::basic_block_sptr get_right_block() = 0;
virtual gr::basic_block_sptr get_left_block(int RF_channel=0)
{
if (RF_channel==0) // avoid unused param warning
{
return NULL; // added to support raw array access (non pure virtual to allow left unimplemented)= 0;
}else{
return NULL; // added to support raw array access (non pure virtual to allow left unimplemented)= 0;
}
}
virtual gr::basic_block_sptr get_right_block(int RF_channel=0)
{
if (RF_channel==0) // avoid unused param warning
{
return NULL; // added to support raw array access (non pure virtual to allow left unimplemented)= 0;
}else{
return NULL; // added to support raw array access (non pure virtual to allow left unimplemented)= 0;
}
}
};
#endif /*GNSS_SDR_GNSS_BLOCK_INTERFACE_H_*/