![]() |
four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
|
00001 // Copyright 2011-2013, Per Zetterberg, KTH Royal Institute of Technology 00002 // 00003 // This program is free software: you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation, either version 3 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00015 // 00016 00017 #include <fstream> 00018 #include <uhd/device.hpp> 00019 #include <uhd/utils/thread_priority.hpp> 00020 #include <uhd/utils/safe_main.hpp> 00021 #include <uhd/usrp/multi_usrp.hpp> 00022 #include <boost/program_options.hpp> 00023 #include <boost/format.hpp> 00024 #include <iostream> 00025 #include <complex> 00026 #include <uhd/types/clock_config.hpp> 00027 #include <four_multi/gps.hpp> 00028 #include <four_multi/four_multi.hpp> 00029 00030 namespace po = boost::program_options; 00031 using namespace boost; 00032 00039 class file_based : public four_multi_node { 00040 00041 public: 00042 00059 file_based(std::string filename_rx, std::string filename_tx, uint32_t buffer_length , std::vector<frame_settings> tdma_def, 00060 uint32_t no_ant1, uint32_t no_ant2, 00061 bool use_external_10MHz, bool use_same_antenna, uint32_t skip_ant, 00062 std::vector<std::string> IP); 00063 00064 00065 00066 ~file_based(); 00067 00068 protected: 00069 double d_gain_rx; 00070 double d_gain_tx; 00071 double d_frequency; 00072 std::vector<frame_settings> d_tdma_def; 00073 virtual frame_settings node_init(void) ; 00074 virtual frame_settings node_process(void) ; 00075 virtual void end_of_run(void) ; 00076 uint32_t d_no_rx_buffer, d_no_tx_buffer, d_no_rx_buffer_so_far, d_no_tx_buffer_so_far; 00077 uint32_t d_frame_ix, d_no_frames; 00078 std::string d_filename_rx, d_filename_tx; 00079 std::vector<const void *> d_tx_storage; 00080 00081 }; 00082 00083 00084 00085 frame_settings file_based::node_init(void) { 00086 uint32_t i1; 00087 00088 00089 d_frame_ix=0; 00090 d_no_rx_buffer_so_far=0; 00091 d_no_tx_buffer_so_far=0; 00092 00093 std::complex<int16_t> *p; 00094 00095 00096 if (d_tdma_def[d_frame_ix].what==TX) { 00097 00098 00099 for (i1=0;i1<d_no_ant;i1++) { 00100 p=(std::complex<int16_t> *) d_tx_storage[i1]; 00101 memcpy ( (void *) d_tx_buffers[i1], 00102 p, 00103 // 00104 d_buffer_length*4 ); 00105 00106 }; 00107 00108 d_no_tx_buffer_so_far++; 00109 00110 }; 00111 00112 00113 return d_tdma_def[0]; 00114 00115 }; 00116 00117 00118 file_based::file_based(std::string filename_rx, std::string filename_tx, uint32_t buffer_length , std::vector<frame_settings> tdma_def, 00119 uint32_t no_ant1, uint32_t no_ant2, 00120 bool use_external_10MHz, bool use_same_antenna, uint32_t skip_ant, std::vector<std::string> IP): 00121 four_multi_node(buffer_length, no_ant1, no_ant2,use_external_10MHz , 00122 use_same_antenna,0,IP,false,skip_ant) 00123 { 00124 00125 d_buffer_length=buffer_length; 00126 d_tdma_def=tdma_def; 00127 00128 d_filename_rx=filename_rx; 00129 d_filename_tx=filename_tx; 00130 00131 d_no_rx_buffer=0; 00132 d_no_tx_buffer=0; 00133 00134 00135 for (uint32_t i1=0;i1<d_tdma_def.size();i1++) { 00136 if ((d_tdma_def[i1].what)==TX) 00137 d_no_tx_buffer++; 00138 if ((d_tdma_def[i1].what)==RX) 00139 d_no_rx_buffer++; 00140 }; 00141 00142 00143 std::complex<int16_t> *temp_buffer; 00144 00145 00146 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00147 temp_buffer=new std::complex<int16_t>[d_buffer_length*d_no_tx_buffer]; 00148 d_tx_storage.push_back(temp_buffer); 00149 }; 00150 00151 00152 if (d_no_rx_buffer>0) 00153 save_raw_input_on_file(d_no_rx_buffer,filename_rx); 00154 00155 00156 00157 if (d_no_tx_buffer>0) { 00158 std::ifstream s1; //(d_filename_tx.c_str(), std::ios::binary); 00159 00160 00161 s1.open(d_filename_tx.c_str(), std::ios::binary); 00162 00163 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00164 s1.read((char *) d_tx_storage[i1],d_buffer_length*d_no_tx_buffer*4); 00165 }; 00166 00167 00168 s1.close(); 00169 00170 } 00171 00172 00173 00174 }; 00175 00176 00177 void file_based::end_of_run(){ 00178 00179 00180 std::cout << "d_no_rx_buffer=" << d_no_rx_buffer << std::endl; 00181 std::cout << "d_buffer_length=" << d_buffer_length << std::endl; 00182 00183 00184 00185 }; 00186 00187 file_based::~file_based(){ 00188 00189 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00190 delete [] (std::complex<int16_t>*) d_tx_storage[i1]; 00191 }; 00192 00193 }; 00194 00195 frame_settings file_based::node_process(void) { 00196 00197 std::complex<int16_t> *p1; 00198 void *p2; 00199 00200 00201 if (d_old_frame_settings.what==RX) { 00202 00203 00204 00205 00206 d_no_rx_buffer_so_far++; 00207 }; 00208 00209 00210 00211 00212 if (d_frame_ix==(d_tdma_def.size()-1)) { 00213 00214 std::cout << "END! \n"; 00215 frame_settings frame; 00216 frame.what=END; 00217 return frame; 00218 } else { 00219 00220 00221 d_frame_ix++; 00222 if (d_tdma_def[d_frame_ix].what==TX) { 00223 for (uint32_t i1=0;i1<d_no_ant;i1++) { 00224 00225 p1=(std::complex<int16_t> *) d_tx_storage[i1]; 00226 p1=&p1[d_no_tx_buffer_so_far*d_buffer_length]; 00227 p2=(void *) d_tx_buffers[i1]; 00228 memcpy (p2, p1, d_buffer_length*4 ); 00229 }; 00230 d_no_tx_buffer_so_far++; 00231 }; 00232 00233 00234 00235 return d_tdma_def[d_frame_ix]; 00236 }; 00237 00238 00239 00240 } 00241 00242 00243 00244 int UHD_SAFE_MAIN(int argc, char *argv[]){ 00245 00246 00247 00248 if (!(uhd::set_thread_priority_safe(1,true))) { 00249 std::cout << "Failed setting priority, using sudo? " << std::endl; 00250 }; 00251 00252 00253 //variables to be set by po 00254 00255 double freq,freq2; 00256 double d_time; 00257 bool use_external_10MHz,trigger_with_pps, use_same; 00258 std::string filename_rx, filename_tx, dev_name; 00259 uint32_t start_time; 00260 float gain_rx, gain_tx, gain_rx2; 00261 uint32_t node_ix, no_ant, Nsamples, Nframes, skip_ant; 00262 double rate; 00263 00264 00265 //setup the program options 00266 po::options_description desc("Allowed options"); 00267 desc.add_options() 00268 ("help", "help message") 00269 ("freq", po::value<double>(&freq)->default_value(2490e6), "rf center frequency in Hz") 00270 ("freq2", po::value<double>(&freq2)->default_value(0), "second center frequency in Hz") 00271 ("10MHz",po::value<bool>(&use_external_10MHz)->default_value(true), 00272 "external 10MHz on 'REF CLOCK' connector (true=1=yes)") 00273 ("use_same",po::value<bool>(&use_same)->default_value(false), 00274 "Use J1 for RX as well as TX") 00275 ("PPS",po::value<bool>(&trigger_with_pps)->default_value(false), 00276 "trigger reception with 'PPS IN' connector (true=1=yes)") 00277 ("filename_tx",po::value<std::string>(&filename_tx)->default_value("data_to_usrp.dat"), 00278 "filename of data to USRP") 00279 ("filename_rx",po::value<std::string>(&filename_rx)->default_value("data_from_usrp.dat"), 00280 "filename of data from USRP") 00281 ("start_time",po::value<uint32_t>(&start_time)->default_value(0), "Start time (GPS ref) h*3600+m*60+s") 00282 ("dev_name",po::value<std::string>(&dev_name)->default_value("/dev/ttyUSB0"), "Name of GPS device") 00283 ("gain_rx",po::value<float>(&gain_rx)->default_value(0), "receiver gain") 00284 ("gain_rx2",po::value<float>(&gain_rx2)->default_value(1000), "second receiver gain") 00285 ("gain_tx",po::value<float>(&gain_tx)->default_value(0), "transmitter gain") 00286 ("node_ix",po::value<uint32_t>(&node_ix)->default_value(0), "node index") 00287 ("no_ant",po::value<uint32_t>(&no_ant)->default_value(1), 00288 "number of antennas (or more precisely - the number of USRP2s") 00289 ("skip_ant",po::value<uint32_t>(&skip_ant)->default_value(0), 00290 "Example: if skip_ant=1 then the first USPR2 should have address 192.168.20.2") 00291 ("Nsamples",po::value<uint32_t>(&Nsamples)->default_value(10000), 00292 "Number of samples per buffer") 00293 ("Nframes",po::value<uint32_t>(&Nframes)->default_value(4), 00294 "Number of frames (Nframes/2 in each direction)") 00295 ("d_time", po::value<double>(&d_time)->default_value(0.012), "time between frames") 00296 ("rate", po::value<double>(&rate)->default_value(25e6), "sample-rate") 00297 00298 ; 00299 po::variables_map vm; 00300 po::store(po::parse_command_line(argc, argv, desc), vm); 00301 po::notify(vm); 00302 00303 if (vm.count("help")){ 00304 std::cout << boost::format("Ping pong %s") % desc << std::endl; 00305 return ~0; 00306 } 00307 00308 00309 /* Here choose tdma_def */ 00310 std::vector<frame_settings> tdma_def; 00311 frame_settings frame; 00312 std::vector<double> temp_double_vector; 00313 std::vector<double> temp_double_vector2; 00314 00315 temp_double_vector.resize(1); 00316 temp_double_vector2.resize(2); 00317 00318 00319 for (uint32_t i1=0;i1<Nframes;i1 ++ ) { 00320 00321 00322 if (freq2>0) { 00323 temp_double_vector2[0]=freq; 00324 temp_double_vector2[1]=freq2; 00325 frame.frequency=temp_double_vector2; 00326 } else { 00327 temp_double_vector[0]=freq; 00328 frame.frequency=temp_double_vector; 00329 }; 00330 00331 if (gain_rx2<1000) { 00332 temp_double_vector[0]=gain_rx; 00333 temp_double_vector[1]=gain_rx2; 00334 frame.gain_rx=temp_double_vector2; 00335 } else { 00336 temp_double_vector[0]=gain_rx; 00337 frame.gain_rx=temp_double_vector; 00338 }; 00339 00340 00341 temp_double_vector[0]=gain_tx; 00342 frame.gain_tx=temp_double_vector; 00343 frame.time=i1*d_time; 00344 00345 if ((i1 % 2)==(node_ix %2)) { 00346 frame.what=RX; 00347 } 00348 else { 00349 frame.what=TX; 00350 //std::cout << "i1=" << i1 << std::endl; 00351 } 00352 00353 tdma_def.push_back(frame); 00354 00355 }; 00356 00357 00358 std::cout << "number of frames=" << tdma_def.size() << std::endl; 00359 00360 std::vector<std::string> IP_addresses; 00361 00362 file_based my_file_based(filename_rx,filename_tx,Nsamples,tdma_def, 00363 no_ant,0,use_external_10MHz,use_same, 00364 skip_ant,std::vector<std::string>(0)) ; 00365 00366 gps_wait_until(dev_name.c_str(),start_time); 00367 00368 std::cout << "OK, we got here!" << std::endl; 00369 00370 my_file_based.run(); 00371 00372 return 0; 00373 } 00374 00375 00376