Advertisement
ANIK123

Untitled

May 21st, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.51 KB | None | 0 0
  1. #include <uhd/utils/thread_priority.hpp>
  2. #include <uhd/utils/safe_main.hpp>
  3. #include <uhd/usrp/multi_usrp.hpp>
  4. #include <uhd/exception.hpp>
  5. #include <uhd/types/tune_request.hpp>
  6. #include <boost/program_options.hpp>
  7. #include <boost/format.hpp>
  8. #include <boost/thread.hpp>
  9. #include <iostream>
  10. #include <fstream>
  11. #include <thread>
  12. #include <csignal>
  13. #include <future>
  14.  
  15. static bool stop_signal_called = false;
  16.  
  17. void sig_int_handler(int) {
  18.     std::cout << "SIG INT HANDLED" << std::endl;
  19.     stop_signal_called = true;
  20. }
  21.  
  22. class USRPController {
  23. public:
  24.     uhd::usrp::multi_usrp::sptr device;
  25.  
  26.     USRPController(std::string serial, double rate, double freq, double gain, std::string file_name,
  27.                    std::string time_source) :
  28.             serial(serial), rate(rate), freq(freq), gain(gain) {
  29.         std::ostringstream string_stream;
  30.         string_stream << "[DEV " << serial << "] ";
  31.         log_prepend = string_stream.str();
  32.         std::stringstream ss;
  33.         ss << log_prepend << "Creating.." << std::endl;
  34.         std::cout << ss.str();
  35.  
  36.         this->device = uhd::usrp::multi_usrp::make("serial=" + serial);
  37.         this->device->set_time_source(time_source); //applies to all mboards
  38.         this->device->set_rx_subdev_spec(std::string("A:A"));
  39.         uhd::time_spec_t cmd_time = device->get_time_now() + uhd::time_spec_t(1.0);
  40.         this->device->set_command_time(cmd_time);
  41.  
  42.         uhd::tune_request_t tune_request(this->freq);
  43.         this->device->set_rx_freq(tune_request);
  44.         this->device->set_rx_gain(this->gain);
  45.         this->device->set_rx_rate(this->rate);
  46.         this->device->set_rx_bandwidth(this->rate);
  47.         this->device->set_rx_antenna("RX2");
  48.  
  49.         //end timed commands
  50.         this->device->clear_command_time();
  51.  
  52.         std::string cpu_format = "fc32";
  53.         std::string wire_format = "sc16";
  54.         uhd::stream_args_t stream_args(cpu_format, wire_format);
  55.         this->rx_stream = this->device->get_rx_stream(stream_args);
  56.  
  57.         full_file_name = "/path/to/records/" + file_name;
  58.  
  59.         size_t samps_per_buff = 10000;// samples per buffer
  60.         this->buff = std::vector<std::complex<float>>(samps_per_buff);
  61.         outfile.open(full_file_name.c_str(), std::ofstream::binary);
  62.     }
  63.  
  64.     void start(uhd::time_spec_t cmd_time) {
  65.         //setup streaming
  66.         uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
  67.         stream_cmd.num_samps = size_t(0);
  68.         stream_cmd.stream_now = false;
  69.         stream_cmd.time_spec = uhd::time_spec_t(cmd_time);
  70.         this->rx_stream->issue_stream_cmd(stream_cmd);
  71.     }
  72.  
  73.     bool work() {
  74.         size_t num_rx_samps = this->rx_stream->recv(&buff.front(), buff.size(), md, 3.0, true);// Try TRUE
  75.  
  76.         if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) {
  77.             std::cout << log_prepend << boost::format("Timeout while streaming") << std::endl;
  78.         } else if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) {
  79.             if (overflow_message) {
  80.                 overflow_message = false;
  81.                 std::cerr << log_prepend << boost::format(
  82.                         "Got an overflow indication. Please consider the following:\n"
  83.                                 "  Your write medium must sustain a rate of %fMB/s.\n"
  84.                                 "  Dropped samples will not be written to the file.\n"
  85.                                 "  Please modify this example for your purposes.\n"
  86.                                 "  This message will not appear again.\n"
  87.                 ) % (this->device->get_rx_rate() * sizeof(std::complex<float>) / 1e6);
  88.             }
  89.             return true;
  90.         } else if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE) {
  91. //            its o'k'?))
  92.         } else {
  93.             std::string error = str(boost::format("Uncaught error at %s %s") % (log_prepend, md.strerror()));
  94.             throw std::runtime_error(error);
  95.         }
  96.  
  97.         if (outfile.is_open()) {
  98.             outfile.write((const char *) &buff.front(), num_rx_samps * sizeof(std::complex<float>));
  99.         }
  100.  
  101.         return true;
  102.     }
  103.  
  104.     uhd::rx_streamer::sptr rx_stream;
  105.  
  106. private:
  107.     std::string serial;
  108.     double rate;
  109.     double freq;
  110.     double gain;
  111.  
  112.     std::vector<std::complex<float>> buff;
  113.     uhd::rx_metadata_t md;
  114.     bool overflow_message = true;
  115.     std::string full_file_name;
  116.     std::string log_prepend;
  117.     std::ofstream outfile;
  118. };
  119.  
  120. void deviceThreadFunc(USRPController *controller) {
  121.     while (not stop_signal_called) {
  122.         if (not controller->work()) break;
  123.     }
  124. }
  125.  
  126. uhd::time_spec_t get_time_now() {
  127.     return uhd::time_spec_t::get_system_time();
  128. }
  129.  
  130. void ppsControl(USRPController *dev1, USRPController *dev2) {
  131.     while (not stop_signal_called) {
  132.         const uhd::time_spec_t dtime1 = dev1->device->get_time_now();
  133.         const uhd::time_spec_t dtime2 = dev2->device->get_time_now();
  134.         const uhd::time_spec_t ttt = get_time_now();
  135.         dev1->device->set_time_now(ttt);
  136.         dev2->device->set_time_now(ttt);
  137.         std::stringstream ss;
  138.         ss << "devs: " << dtime1.get_full_secs() << "." << dtime1.get_tick_count(1e6) << " " << dtime2.get_full_secs()
  139.            << "." << dtime2.get_tick_count(1e6) << " is ";
  140.         if (dtime1.get_real_secs() != dtime2.get_real_secs()) ss << "not same";
  141.         else ss << "same!";
  142.         ss << ", diff " << (dtime1.get_tick_count(1e6) - dtime2.get_tick_count(1e6)) << ", pc: "
  143.            << ttt.get_tick_count(1e6);
  144.         ss << std::endl;
  145.         std::cout << ss.str();
  146.         boost::this_thread::sleep(boost::posix_time::milliseconds(100));
  147.     }
  148. }
  149.  
  150. void create_device(std::promise<USRPController *> &&p, std::string serial, double rate, double freq,
  151.                    double gain, std::string file_name, std::string time_source) {
  152.     USRPController *device = new USRPController(serial, rate, freq, gain, file_name, time_source);
  153.     p.set_value(device);
  154. }
  155.  
  156. int UHD_SAFE_MAIN(int argc, char *argv[]) {
  157.     uhd::set_thread_priority_safe();
  158.  
  159.     std::signal(SIGINT, &sig_int_handler);
  160.     std::signal(SIGHUP, &sig_int_handler);
  161.  
  162.     double rate(5e6);
  163.     double gain(32);
  164.  
  165.     std::promise<USRPController *> promise_1;
  166.     std::promise<USRPController *> promise_2;
  167.     auto f1 = promise_1.get_future();
  168.     auto f2 = promise_2.get_future();
  169.     std::thread dev_create_thread_1(&create_device, std::move(promise_1), "serial1", rate, 500e6, gain,
  170.                                     "channels1", "internal");
  171.     std::thread dev_create_thread_2(&create_device, std::move(promise_2), "serial2", rate, 500e6, gain,
  172.                                     "channels2", "internal");
  173.     dev_create_thread_1.join();
  174.     dev_create_thread_2.join();
  175.     USRPController *device_one = f1.get();
  176.     USRPController *device_two = f2.get();
  177.  
  178.     boost::this_thread::sleep(boost::posix_time::seconds(1));
  179.  
  180.     std::thread ppmControlThread(ppsControl, device_one, device_two);
  181.  
  182.     boost::this_thread::sleep(boost::posix_time::seconds(5));
  183.  
  184.     uhd::time_spec_t start_timeout = uhd::time_spec_t(1.0);
  185.     uhd::time_spec_t cmd_time_one = device_one->device->get_time_now() + start_timeout;
  186.     uhd::time_spec_t cmd_time_two = device_two->device->get_time_now() + start_timeout;
  187.  
  188.     device_one->start(cmd_time_one);
  189.     device_two->start(cmd_time_two);
  190.  
  191.     std::thread first(deviceThreadFunc, device_one);
  192.     std::thread second(deviceThreadFunc, device_two);
  193.  
  194.     first.join();
  195.     second.join();
  196.  
  197.     return EXIT_SUCCESS;
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement