four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
examples/SISO_AMC_OFDM_node.cpp
00001 //
00002 // Copyright 2011-2013, Per Zetterberg, KITH Royal Institute of Technology
00003 //
00004 // This program is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include "SISO_AMC_OFDM_node.hpp"
00019 #include <four_multi/four_multi.hpp>
00020 #include <itpp/itcomm.h>
00021 #include <itpp/stat/misc_stat.h>
00022 
00023 
00024 SISO_AMC_OFDM_node::SISO_AMC_OFDM_node(float gain_rx, 
00025 float gain_tx,uint32_t node_ix , double frequency,
00026                        bool same_antenna,
00027                                        uint32_t modulation_order, bool simulate, uint32_t codec_ix, bool chase,
00028 double delta_time)
00029   : four_multi_node(buffer_size,1,0,true,same_antenna,node_ix,
00030                std::vector<std::string>(0),simulate,0)
00031 {
00032  
00033   
00034    ivec reorder="0:20";
00035    ivec known_symbol_pos="10";
00036    ai.init(false,false,12,21,known_symbol_pos,reorder);
00037 
00038    d_modulation_order=modulation_order;
00039    d_codec_ix=codec_ix;
00040    d_chase=chase;
00041    d_delta_time=delta_time;
00042 
00043    word_length=38*5*2*4;
00044    amc.init(word_length,true);
00045    max_message_length=amc.codec_message_size(amc.no_of_codecs()-1);
00046 
00047    transmitted.set_length(word_length);
00048    soft_bit.set_length(word_length);
00049    input.set_length(max_message_length+1000);
00050    decoded_bits.set_length(max_message_length);
00051    
00052    symbols.set_length(word_length/2); // QPSK lowest modulation
00053    symbols_chase.set_length(word_length/2); // QPSK lowest modulation
00054    
00055    message_hat.set_length(max_message_length);
00056    transmitted.set_length(word_length);
00057    transmitted_hat.set_length(word_length);
00058 
00059 
00060    //amc.run_through_all_mcs(); // To see the performance of modulation&coding
00061    //exit(1);
00062 
00063    d_gain_rx=gain_rx;
00064    d_no_frames=4;
00065    d_node_ix=node_ix % 2;
00066    d_frame_ix=0;
00067    d_frequency=frequency;
00068    d_gain_tx=gain_tx;
00069    d_frame_ix=0;
00070    scaling_tx_signal=70000;
00071 
00072    waveform_rx.set_length(buffer_size);
00073    waveform_tx.set_length(buffer_size);
00074    waveform_rx.zeros();
00075    waveform_tx.zeros();
00076    
00077 }
00078 
00079 
00080 SISO_AMC_OFDM_node::~SISO_AMC_OFDM_node() {
00081 
00082 };
00083 
00084 
00085 frame_settings SISO_AMC_OFDM_node::node_init(void) {
00086 
00087 
00088   d_frame_ix=0;
00089 
00090   ber_i=0;  
00091   BER.set_length(d_no_frames*log2(d_modulation_order)/2);
00092   BERraw.set_length(d_no_frames*log2(d_modulation_order)/2);
00093   
00094 
00095   if (node_ix()==1) {
00096     return node_process(); // TX
00097   } else { //RX
00098     frame_settings frame;
00099     std::vector<double> gain_rx_vec(1);
00100     std::vector<double> gain_tx_vec(1);
00101     std::vector<double> freq_vec(1);
00102   
00103     gain_rx_vec[0]=d_gain_rx;
00104     gain_tx_vec[0]=d_gain_rx;
00105     freq_vec[0]=d_frequency;
00106     frame.what=RX;
00107     frame.gain_rx=gain_rx_vec;
00108     frame.gain_tx=gain_tx_vec;
00109     frame.time=0.0;
00110     frame.frequency=freq_vec;
00111 
00112     return frame;
00113   };
00114 
00115 };
00116 
00117 
00118 
00119 
00120 void SISO_AMC_OFDM_node::end_of_run(){
00121 };
00122 
00123 frame_settings SISO_AMC_OFDM_node::node_process(void) {
00124 
00125 
00126   frame_settings frame;
00127   std::vector<double> gain_rx_vec(1);
00128   std::vector<double> gain_tx_vec(1);
00129   std::vector<double> freq_vec(1);
00130   //bvec transmitted, input;
00131   //int codec_ix=0;
00132 
00133   //transmitted.set_length((ai.Ns-1)*ai.length_ix*qam.bits_per_symbol());
00134   //transmitted.set_length(10000);
00135   //input.set_length(block_length);
00136   gain_rx_vec[0]=d_gain_rx;
00137   gain_tx_vec[0]=d_gain_rx;
00138   freq_vec[0]=d_frequency;
00139 
00140   frame.frequency=freq_vec;
00141   frame.gain_rx=gain_rx_vec;
00142   frame.gain_tx=gain_tx_vec;
00143 
00144   d_frame_ix++;
00145 
00146 
00147   if (node_ix()==0) { /****** RX ***********/
00148 
00149       frame.time=d_frame_ix*d_delta_time;
00150       
00151       /* Data is available in d_rx_buffers[0] */
00152 
00153       std::cout << "Processing in the receiver \n";
00154 
00155       std::complex<int16_t> *p1;
00156       p1=(std::complex<int16_t> *) d_rx_buffers[0];
00157       for (uint32_t i1=0;i1<buffer_size;i1++) 
00158         waveform_rx[i1]=p1[i1];
00159 
00160 
00161       //amc.skip_symbols=0;
00162       int start_sample;
00163       if (d_simulate) {
00164          start_sample=shift_transmit_signal_samples+6;
00165       } else {
00166          start_sample=shift_transmit_signal_samples+6+55;
00167       };
00168       double rms_signalr;
00169       cvec h(ai.length_ix_all);
00170 
00171       ivec t2=ai.start_of_known_symbol();
00172       ai.estimate_channel(waveform_rx.mid(start_sample+t2(0),ai.Nfft)
00173                           ,noise_variance_norm,h,noise_variance); 
00174 
00175                         
00176       ai.demodulate(waveform_rx,symbols,start_sample,h,rms_signalr);     
00177       ai.de_interleave_symbols(symbols, d_frame_ix);
00178 
00179       #if 0
00180       if (d_frame_ix==1) {
00181         itpp::it_file d1;
00182         d1.open("d1.it");
00183         d1<< itpp::Name("waveform_rx") << waveform_rx;
00184         d1<< itpp::Name("symbols") << symbols;
00185         d1.close();
00186       };
00187       #endif
00188 
00189 
00190      if (d_frame_ix==1) {
00191         noise_variance_chase=noise_variance_norm;
00192         symbols_chase=symbols;
00193       } else {
00194         double c1,c2,c;
00195 
00196         c1=1/sqrt(noise_variance_chase);
00197         c2=1/sqrt(noise_variance_norm);
00198         c=c1+c2;
00199         c1=c1/c;
00200         c2=c2/c;
00201 
00202         symbols_chase=c1*symbols_chase+c2*symbols;
00203         noise_variance_chase=1/((1/noise_variance_chase)+
00204                                    (1/noise_variance_norm));
00205       };
00206     
00207       
00208       decode_rx_symbols(d_codec_ix,d_modulation_order,d_chase);
00209       frame.what=RX;
00210 
00211       if (d_frame_ix==(d_no_frames)) 
00212         frame.what=END;
00213 
00214       
00215 
00216 
00217   };
00218 
00219 
00220 
00221   if (node_ix()==1) { // TX
00222 
00223 
00224     frame.time=(d_frame_ix-1)*d_delta_time;
00225     std::cout << "Processing in the transmitter \n";
00226     
00227     waveform_tx.zeros();
00228 
00229     //RNG_reset(100+d_frame_ix);
00230     //cout << "i2=" << input << ";"  << endl;
00231 
00232     format_tx_symbols(d_codec_ix,d_modulation_order);
00233     ai.interleave_symbols(symbols, d_frame_ix);
00234 
00235 
00236     double rms_power=-10;
00237     ai.modulate(waveform_tx,symbols,shift_transmit_signal_samples,rms_power,
00238                 ones_c(ai.length_ix_all));
00239     waveform_tx*=scaling_tx_signal;
00240 
00241     std::complex<int16_t> *p1;
00242     p1=(std::complex<int16_t> *) d_tx_buffers[0];
00243     for (uint32_t i1=0;i1<buffer_size;i1++) 
00244       p1[i1]=waveform_tx[i1];
00245 
00246 
00247 
00248 
00249     #if 0
00250     it_file d1;
00251     d1.open("d1.it");
00252     d1 << Name("symbols") << symbols ;
00253     d1<< Name("waveform_tx") << waveform_tx;
00254     d1.close();
00255     exit(1);
00256     #endif
00257 
00258     frame.what=TX;
00259 
00260     if (d_frame_ix==(d_no_frames+1)) 
00261       frame.what=END;
00262   };
00263   
00264 
00265   return frame;
00266   
00267 
00268 }
00269 
00270 void SISO_AMC_OFDM_node::format_tx_symbols(uint32_t codec_ix, uint32_t modulation_order) 
00271 {
00272 
00273   cout << "codec_ix=" << codec_ix << endl;
00274 
00275 
00276   int l=amc.codec_message_size(codec_ix);
00277 
00278 
00279   seed=100;
00280   RNG_reset(100);
00281   //input.set_subvector(0,randb(l));
00282   amc.randb_thread_safe(0,l,input,&seed);
00283   amc.modulate(modulation_order,codec_ix,input.mid(0,l),
00284                transmitted,symbols,0) ;    
00285 
00286 
00287  
00288 
00289 
00290   if (modulation_order>15) {
00291       seed=110;
00292       RNG_reset(110);
00293       //input.set_subvector(0,randb(l));
00294       amc.randb_thread_safe(0,l,input,&seed);
00295       amc.modulate(modulation_order,codec_ix,input.mid(0,l),
00296                    transmitted,symbols,word_length/(log2(modulation_order))); 
00297   };
00298 
00299   if (modulation_order>63) {
00300       seed=120;
00301       RNG_reset(120);
00302       //input.set_subvector(0,randb(l));
00303       amc.randb_thread_safe(0,l,input,&seed);
00304       amc.modulate(modulation_order,codec_ix,input.mid(0,l),
00305                    transmitted,symbols,2*word_length/(log2(modulation_order)));
00306     
00307   };
00308   if (modulation_order>255) {
00309       //RNG_reset(130);
00310       seed=130;
00311       input.set_subvector(0,randb(l));
00312       amc.randb_thread_safe(0,l,input,&seed);
00313       amc.modulate(modulation_order,codec_ix,input.mid(0,l),
00314                    transmitted,symbols,3*word_length/(log2(modulation_order)));
00315   };
00316 
00317 };
00318 
00319 
00320 void SISO_AMC_OFDM_node::decode_rx_symbols(uint32_t codec_ix, uint32_t modulation_order,
00321 bool use_chase_combining) 
00322 { 
00323   
00324   int l=amc.codec_message_size(codec_ix);
00325 
00326 
00327   RNG_reset(100);
00328   seed=100;
00329   //input.set_subvector(0,randb(l));
00330   amc.randb_thread_safe(0,l,input,&seed);
00331   amc.encode(codec_ix,input.mid(0,l),transmitted) ;
00332 
00333 
00334   if (use_chase_combining) {
00335     amc.demodulate(symbols_chase.mid(0,word_length/log2( modulation_order)),
00336                    noise_variance_chase,
00337                   modulation_order,codec_ix,message_hat,transmitted_hat);
00338   } else {
00339     amc.demodulate(symbols.mid(0,word_length/log2( modulation_order)),
00340                           noise_variance_norm,
00341                   modulation_order,codec_ix,message_hat,transmitted_hat);
00342 
00343   };
00344 
00345 
00346   berc.clear();
00347   berc.count(transmitted,transmitted_hat);  
00348   BERraw[ber_i]=berc.get_errorrate();
00349   //cout << "BER(raw)=" << BER[0] << endl;
00350   berc.clear();
00351   berc.count(input.mid(0,l),message_hat.mid(0,l));  
00352   BER[ber_i]=berc.get_errorrate();
00353   //cout << "BER=" << BER[0] << endl;
00354   ber_i++;
00355 
00356 
00357   if (modulation_order>15) {
00358     RNG_reset(110);
00359     seed=110;
00360     //input.set_subvector(0,randb(l));
00361     amc.randb_thread_safe(0,l,input,&seed);
00362     amc.encode(codec_ix,input.mid(0,l),transmitted) ;
00363 
00364     if (use_chase_combining) {
00365       amc.demodulate(symbols_chase.mid(word_length/log2( modulation_order),
00366                                  word_length/log2( modulation_order)),
00367                           noise_variance_chase,
00368                   modulation_order,codec_ix,message_hat,transmitted_hat);   
00369     } else {  
00370       amc.demodulate(symbols.mid(word_length/log2( modulation_order),
00371                                  word_length/log2( modulation_order)),
00372                           noise_variance_norm,
00373                   modulation_order,codec_ix,message_hat,transmitted_hat);
00374     };
00375       
00376     berc.clear();
00377     berc.count(transmitted,transmitted_hat);  
00378     BERraw[ber_i]=berc.get_errorrate();
00379     //cout << "BER(raw)=" << BER[0] << endl;
00380     berc.clear();
00381     berc.count(input.mid(0,l),message_hat.mid(0,l));  
00382     BER[ber_i]=berc.get_errorrate();
00383     //cout << "BER=" << BER[0] << endl;
00384     ber_i++;
00385 
00386   };
00387 
00388   if (modulation_order>63) {
00389 
00390       RNG_reset(120);
00391       seed=120;
00392       //input.set_subvector(0,randb(l));
00393       amc.randb_thread_safe(0,l,input,&seed);
00394       amc.encode(codec_ix,input.mid(0,l),transmitted) ;
00395       if (use_chase_combining) 
00396         amc.demodulate(symbols_chase.mid(2*word_length
00397                                          /log2( modulation_order),
00398                                  word_length/log2( modulation_order)),
00399                           noise_variance_chase,
00400                   modulation_order,codec_ix,message_hat,transmitted_hat);
00401       else
00402         amc.demodulate(symbols.mid(2*word_length/log2( modulation_order),
00403                                  word_length/log2( modulation_order)),
00404                           noise_variance_norm,
00405                   modulation_order,codec_ix,message_hat,transmitted_hat);
00406       
00407       berc.clear();
00408       berc.count(transmitted,transmitted_hat);  
00409       BERraw[ber_i]=berc.get_errorrate();
00410       //cout << "BER(raw)=" << BER[0] << endl;
00411       berc.clear();
00412       berc.count(input.mid(0,l),message_hat.mid(0,l));  
00413       BER[ber_i]=berc.get_errorrate();
00414       //cout << "BER=" << BER[0] << endl;
00415       ber_i++;
00416 
00417 
00418 
00419   };
00420   if (modulation_order>255) {
00421     
00422     RNG_reset(130);
00423     seed=130;
00424 
00425     //input.set_subvector(0,randb(l));
00426     amc.randb_thread_safe(0,l,input,&seed);
00427     amc.encode(codec_ix,input.mid(0,l),transmitted) ;
00428     if (use_chase_combining) 
00429       amc.demodulate(symbols_chase.mid(3*word_length/log2( modulation_order),
00430                                  word_length/log2( modulation_order)),
00431                           noise_variance_chase,
00432                   modulation_order,codec_ix,message_hat,transmitted_hat);
00433     else
00434       amc.demodulate(symbols.mid(3*word_length/log2( modulation_order),
00435                                  word_length/log2( modulation_order)),
00436                           noise_variance_norm,
00437                   modulation_order,codec_ix,message_hat,transmitted_hat);
00438       
00439     berc.clear();
00440     berc.count(transmitted,transmitted_hat);  
00441     BERraw[ber_i]=berc.get_errorrate();
00442     //cout << "BER(raw)=" << BER[0] << endl;
00443     berc.clear();
00444     berc.count(input.mid(0,l),message_hat.mid(0,l));  
00445     BER[ber_i]=berc.get_errorrate();
00446     //cout << "BER=" << BER[0] << endl;
00447     ber_i++;
00448 
00449 
00450 
00451   };
00452 
00453 
00454 };
 All Classes Functions Variables