Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/experiment_prototype/experiment_prototype.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ class ExperimentPrototype:
requires tuning time to set, it cannot be modified after
instantiation.
:type rxctrfreq: float
:param lo_lock_wait: Determines if the usrp driver will wait for the local oscillator
to reach a locked state before continuing when tuning the tx and
rx center frequencies. Otherwise a default time delay is used
:type lo_lock_wait: bool
:param comment_string: Description of experiment for data files. This should be used to
describe your overall experiment design. Another comment string
exists for every slice added, to describe information that is
Expand All @@ -157,7 +161,7 @@ class ExperimentPrototype:
"""

def __init__(self, cpid, output_rx_rate=default_output_rx_rate, rx_bandwidth=default_rx_bandwidth,
tx_bandwidth=5.0e6, txctrfreq=12000.0, rxctrfreq=12000.0, comment_string=''):
tx_bandwidth=5.0e6, txctrfreq=12000.0, rxctrfreq=12000.0, lo_lock_wait=False, comment_string=''):
if not isinstance(cpid, int):
errmsg = 'CPID must be a unique int'
raise ExperimentException(errmsg)
Expand Down Expand Up @@ -249,6 +253,8 @@ def __init__(self, cpid, output_rx_rate=default_output_rx_rate, rx_bandwidth=def
clock_divider = math.ceil(rxctrfreq*1e3/clock_multiples)
self.__rxctrfreq = (clock_divider * clock_multiples)/1e3

self.__lo_lock_wait = bool(lo_lock_wait)

# This is experiment-wide transmit metadata necessary to build the pulses. This data
# cannot change within the experiment and is used in the scan classes to pass information
# to where the samples are built.
Expand Down Expand Up @@ -569,6 +575,17 @@ def rx_minfreq(self):
log.warning(f"Minimum receive frequency set to 1 kHz")
return 1000 # Hz

@property
def lo_lock_wait(self):
"""
True or false statement indicating if the usrp driver will wait for the local oscillator
to reach a locked stated, or otherwise use a default time delay.

:returns: lo_lock_wait
:rtype: bool
"""
return self.__lo_lock_wait

@property
def interface(self):
"""
Expand Down
15 changes: 11 additions & 4 deletions src/radar_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
TIME_PROFILE = False


def setup_driver(radctrl_to_driver, driver_to_radctrl_iden, txctrfreq, rxctrfreq, txrate, rxrate):
def setup_driver(radctrl_to_driver, driver_to_radctrl_iden, txctrfreq, rxctrfreq, txrate, rxrate,
lo_lock_wait=False):
"""
First packet sent to driver for setup.

Expand All @@ -49,6 +50,7 @@ def setup_driver(radctrl_to_driver, driver_to_radctrl_iden, txctrfreq, rxctrfreq
"""

driverpacket = DriverPacket()
driverpacket.lo_lock_wait = lo_lock_wait
driverpacket.txcenterfreq = txctrfreq * 1000 # convert to Hz
driverpacket.rxcenterfreq = rxctrfreq * 1000 # convert to Hz
driverpacket.txrate = txrate
Expand All @@ -60,7 +62,8 @@ def setup_driver(radctrl_to_driver, driver_to_radctrl_iden, txctrfreq, rxctrfreq


def data_to_driver(radctrl_to_driver, driver_to_radctrl_iden, samples_array, txctrfreq, rxctrfreq, txrate, rxrate,
numberofreceivesamples, seqtime, SOB, EOB, timing, seqnum, align_sequences, repeat=False):
numberofreceivesamples, seqtime, SOB, EOB, timing, seqnum, align_sequences, repeat=False,
lo_lock_wait=False):
"""
Place data in the driver packet and send it via zeromq to the driver.

Expand Down Expand Up @@ -88,6 +91,8 @@ def data_to_driver(radctrl_to_driver, driver_to_radctrl_iden, samples_array, txc
:param repeat: a boolean indicating whether the pulse is the exact same as the last pulse
in the sequence, in which case we will save the time and not send the samples list and other
params that will be the same.
:param lo_lock_wait: a boolean indicating if the usrp driver should wait for the local oscillator to reach
a locked state when tuning the center frequency. If not then a default time delay is used in while tuning
"""

driverpacket = DriverPacket()
Expand All @@ -98,6 +103,7 @@ def data_to_driver(radctrl_to_driver, driver_to_radctrl_iden, samples_array, txc
driverpacket.numberofreceivesamples = numberofreceivesamples
driverpacket.seqtime = seqtime
driverpacket.align_sequences = align_sequences
driverpacket.lo_lock_wait = lo_lock_wait

if repeat:
# antennas empty
Expand Down Expand Up @@ -496,7 +502,7 @@ def main():
# Wait for acknowledgment that USRP object is set up.
setup_driver(radar_control_to_driver, options.driver_to_radctrl_identity,
experiment.txctrfreq, experiment.rxctrfreq, experiment.txrate,
experiment.rxrate)
experiment.rxrate, lo_lock_wait=experiment.lo_lock_wait)

first_aveperiod = True
next_scan_start = None
Expand Down Expand Up @@ -743,7 +749,8 @@ def send_pulses():
pulse_transmit_data['timing'],
seqnum_start + num_sequences,
sequence.align_sequences,
repeat=pulse_transmit_data['isarepeat'])
repeat=pulse_transmit_data['isarepeat'],
lo_lock_wait=experiment.lo_lock_wait)

if TIME_PROFILE:
pulses_to_driver_time = datetime.utcnow() - start_time
Expand Down
26 changes: 20 additions & 6 deletions src/usrp_drivers/usrp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ double USRP::get_tx_rate(uint32_t channel)
* used and what order they are in. To synchronize tuning of all boxes, timed commands are used so
* that everything is done at once.
*/
double USRP::set_tx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay)
double USRP::set_tx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay, bool lo_lock_wait)
{
uhd::tune_request_t tune_request(freq);

Expand All @@ -154,8 +154,15 @@ double USRP::set_tx_center_freq(double freq, std::vector<size_t> chs, uhd::time_
}
clear_command_time();

auto duration = std::chrono::duration<double>(tune_delay.get_real_secs());
std::this_thread::sleep_for(duration);
// Wait for the LO to settle, or wait for a predefined delay time
if ( lo_lock_wait ) {
while ( not usrp_->get_tx_sensor("lo_locked").to_bool() ) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
} else {
auto duration = std::chrono::duration<double>(tune_delay.get_real_secs());
std::this_thread::sleep_for(duration);
}

//check for varying USRPs
for (auto &channel : chs) {
Expand Down Expand Up @@ -274,7 +281,7 @@ double USRP::get_rx_rate(uint32_t channel)
* used. To synchronize tuning of all boxes, timed commands are used so that everything is done at
* once.
*/
double USRP::set_rx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay)
double USRP::set_rx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay, bool lo_lock_wait)
{
uhd::tune_request_t tune_request(freq);

Expand All @@ -284,8 +291,15 @@ double USRP::set_rx_center_freq(double freq, std::vector<size_t> chs, uhd::time_
}
clear_command_time();

auto duration = std::chrono::duration<double>(tune_delay.get_real_secs());
std::this_thread::sleep_for(duration);
// Wait for the LO to settle, or wait for a predefined delay time
if ( lo_lock_wait ){
while ( not usrp_->get_rx_sensor("lo_locked").to_bool() ) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
} else {
auto duration = std::chrono::duration<double>(tune_delay.get_real_secs());
std::this_thread::sleep_for(duration);
}

//check for varying USRPs
for (auto &channel : chs) {
Expand Down
4 changes: 2 additions & 2 deletions src/usrp_drivers/usrp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ class USRP{
void set_tx_subdev(std::string tx_subdev);
double set_tx_rate(std::vector<size_t> chs);
double get_tx_rate(uint32_t channel=0);
double set_tx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay);
double set_tx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay, bool lo_lock_wait);
double get_tx_center_freq(uint32_t channel=0);
void set_main_rx_subdev(std::string main_subdev);
void set_interferometer_rx_subdev(std::string interferometer_subdev,
uint32_t interferometer_antenna_count);
double set_rx_rate(std::vector<size_t> rx_chs);
double get_rx_rate(uint32_t channel=0);
double set_rx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay);
double set_rx_center_freq(double freq, std::vector<size_t> chs, uhd::time_spec_t tune_delay, bool lo_lock_wait);
double get_rx_center_freq(uint32_t channel=0);
void set_time_source(std::string source, std::string clk_addr);
void check_ref_locked();
Expand Down
36 changes: 30 additions & 6 deletions src/usrp_drivers/usrp_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ void transmit(zmq::context_t &driver_c, USRP &usrp_d, const DriverOptions &drive
DEBUG_MSG(COLOR_BLUE("TRANSMIT") << " burst flags: SOB " << driver_packet.sob() <<
" EOB " << driver_packet.eob());

// Draven added these to keep tabs on the frequencies when they might be switched
DEBUG_MSG(COLOR_RED("TRANSMIT") << " TX borealis center freq " << tx_center_freq <<
" vs driver center freq " << driver_packet.txcenterfreq());
DEBUG_MSG(COLOR_RED("TRANSMIT") << " RX borealis center freq " << rx_center_freq <<
" vs driver center freq " << driver_packet.rxcenterfreq());

TIMEIT_IF_TRUE_OR_DEBUG(false, COLOR_BLUE("TRANSMIT") << " center freq ",
[&]() {
Expand All @@ -198,7 +203,8 @@ void transmit(zmq::context_t &driver_c, USRP &usrp_d, const DriverOptions &drive
driver_packet.txcenterfreq());
tx_center_freq = usrp_d.set_tx_center_freq(driver_packet.txcenterfreq(),
tx_channels,
uhd::time_spec_t(TUNING_DELAY));
uhd::time_spec_t(TUNING_DELAY),
driver_packet.lo_lock_wait());
}
}

Expand All @@ -210,7 +216,8 @@ void transmit(zmq::context_t &driver_c, USRP &usrp_d, const DriverOptions &drive
driver_packet.rxcenterfreq());
rx_center_freq = usrp_d.set_rx_center_freq(driver_packet.rxcenterfreq(),
receive_channels,
uhd::time_spec_t(TUNING_DELAY));
uhd::time_spec_t(TUNING_DELAY),
driver_packet.lo_lock_wait());
}
}

Expand Down Expand Up @@ -638,10 +645,27 @@ int32_t UHD_SAFE_MAIN(int32_t argc, char *argv[]) {

USRP usrp_d(driver_options, driver_packet.txrate(), driver_packet.rxrate());
auto tune_delay = uhd::time_spec_t(TUNING_DELAY);
usrp_d.set_tx_center_freq(driver_packet.txcenterfreq(), driver_options.get_transmit_channels(),
tune_delay);
usrp_d.set_rx_center_freq(driver_packet.rxcenterfreq(), driver_options.get_receive_channels(),
tune_delay);

// Added debug messages and timing to track initial N200 tuning during debug
DEBUG_MSG(COLOR_GREEN("STARTUP") << " center freqs: TX = " << driver_packet.txcenterfreq() <<
" RX = " << driver_packet.rxcenterfreq());
if (driver_packet.lo_lock_wait() == true)
{
DEBUG_MSG(COLOR_GREEN("STARTUP") << " Tuning will wait for lo lock ");
} else {
DEBUG_MSG(COLOR_GREEN("STARTUP") << " Tuning Delay is set to " << TUNING_DELAY);
}

TIMEIT_IF_TRUE_OR_DEBUG(false, COLOR_GREEN("STARTUP") << " Initial tuning to center freq (tx & rx) ",
[&]() {

usrp_d.set_tx_center_freq(driver_packet.txcenterfreq(), driver_options.get_transmit_channels(),
tune_delay, driver_packet.lo_lock_wait());
usrp_d.set_rx_center_freq(driver_packet.rxcenterfreq(), driver_options.get_receive_channels(),
tune_delay, driver_packet.lo_lock_wait());
}()

);


auto driver_ready_msg = std::string("DRIVER_READY");
Expand Down
1 change: 1 addition & 0 deletions src/utils/protobuf/driverpacket.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ message DriverPacket {
bool SOB = 10;
bool EOB = 11;
bool align_sequences = 12;
bool lo_lock_wait = 13;

message SamplesBuffer {
repeated float real = 1;
Expand Down