usrp lecture per zetterberg. tools we use ubuntu 12.04 (ui: gnome or unity) google for tutorials...
Post on 03-Jan-2016
229 Views
Preview:
TRANSCRIPT
USRP Lecture
Per Zetterberg
Tools We use ubuntu 12.04 (UI: gnome or unity)
Google for tutorials etc. Editing textfiles in Emacs:
Tutorial:http://www2.lib.uchicago.edu/keith/tcl-course/emacs-tutorial.html Coding language C++
“C++ primer” by Lippman and Lajoie, cplusplus.com The KTH USRP skeleton code and Matlab interface
Command documentation (“help”) and source code. Compiling source code:
g++ (http://gcc.gnu.org/), make (https://www.gnu.org/software/make/)
Debugging
printf, cout, save/load from/to file ddd (data display debugger) (http://www.gnu.org/software/ddd/manual/html_mono/ddd.html)
Signal processing & communications library
IT++ (http://itpp.sourceforge.net//) Code repository and versioning
git (http://toroid.org/ams/git-central-repo-howto) USRP N210 (www.ettus.com)
AND THESE SLIDES!
Skeleton Code
Download the skeleton code from repository using
Register a (free) account on github, email me your username Wait for confirmation from me. git clone https://github.com/pzett/kth_usrp_utilities.git
Skeleton code files:
rx_60GHz.cpp, rx_60GHz.m tx_60GHz.cpp, tx_60GHz.m harness.cpp, harness.m, square_all_elements_of_array.m,
square_all_elements_of_array.cpp Makefile Etc.
How build the code
Make all Creates: rx_60GHz, tx_GHz, harness (executable files)
Using (our) Matlab interface for USRP
On TX computer: Check that USRP is properly connected (uhd_find_devices).Start matlab in a directory where the skeleton code is located.Create a vector to transmit e.g y=1000*exp(j*0.1*2*pi*(1:10000));Elements of X should be complex with real and imag [-2^15,2^15-1].Transmit the data tx.m or tx_60GHz.m <----- Repeats the data until interruptedEg: tx(length(y),5.5e9,y,0,10,25e6,10e6);
On RX computer:
Check that USRP is properly connected (uhd_find_devices).Start matlab in a directory where the skeleton code is located.Receive the signal rx.m or rx_60GHz.m. E.g X=rx(10000,5.5e9,0,15,25e6,10e6);
tx.m,tx_60GHz.m
tx( Nsamples,RF_freq, X, ref_clk, gain, tx_rate, LOoffset, low_res)
Recommendations:
Nsamples=length(X) or Nsamples=length(X)+guard
RF_freq=5.5e9 or 5.6e9
X: Signal to be transmitted (complex). RMS <= 5000.
ref_clk=0;
gain 0-20
tx_rate=25e6
LOoffset=10e6
tx_60GHz.m
I will give you info later.
rx.m, rx_60GHz.m
X=rx(Nsamples,RFfreq,ref_clk,gain,rx_rate,LOoffset);
Recommendation:Nsamples: Two times longer than transmit signalRFfreq: 5.5e9 or 5.6e9ref_clk=0gain=0,15 or 30.tx_rate=25e6LOoffset=10e6
rx_60GHz.m:I will give you info later.
To remove LO leakage:t=(-10:10)+1e-5;hlp=sin(2*pi*0.3*t)./t;X=conv(X,hlp);
Compiling Compile source without Makefile:
g++ -o test test.cpp
In our Makefile:
CXXFLAGS = -o3 -Wall -DNDEBUG
LDLIBS = -luhd -lboost_program_options
...
tx_60GHz: tx_60GHz.o
$(CXX) -o $@ $^ $(LDLIBS)
Compiling with Makefile
>make tx_60GHz
g++ -o3 -Wall -DNDEBUG -c -o tx_60GHz.o tx_60GHz.cpp
g++ -o tx_60GHz tx_60GHz.o -luhd -lboost_program_options
> make tx_60GHz
make: 'tx_60GHx' is up to date
Parameters, compilation flags, librariesto link width
The executable tx_60GHz depends on tx_60GHz.o. Since there is a file tx_60GHz.cppin the folder, “make” understands thatit should compile it obtain tx_60GHz.o.
Passing command line parameters to c++-program: classic way
#include <iostream>
#include <stdlib.h>
int main(int argc, char **argv) {
double input=atof(argv[1]);
std::cout << “input=” << input << “\n”;
return 0;
};
> ./main 23.23
input=23.23
>
Program
Execution
Passing command line parameters to c++program: boost::program_options
po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") /* command-line perfix, type, help string */ ("no_elements", po::value<int>(&number_of_elements)->default_value(10), "number of elements in vector") ("dummy_str",po::value<std::string>(&dummy_string)->default_value("Default string"), "dummy string") ("dummy_fl",po::value<float>(&dummy_float)->default_value(3.14), "dummy float") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm);
//print the help message if (vm.count("help")){ std::cout << boost::format("harness: %s") % desc << std::endl; return ~0; }
std::cout<< "dummy_string=" << dummy_string << std::endl;std::cout<< "dummy_float=" << dummy_float << std::endl;std::cout << "number_of_elements=" << number_of_elements << std::endl;
./harness ---dummy_fl=2.12dummy_string=Default stringdummy_float=2.12number_of_elements=10
Program
Execution
Calling program from Matlab
./harness ---dummy_fl=2.12dummy_float=2.12;system(['./harness –dummy_fl=',num2str(dummy_float),';']);
Transfering larger amount of data. In Matlab:
fid=fopen('data_to_harness.dat','w');fwrite(fid,data_to_harness,'float');fclose(fid);
Reading the data from C++ program:
std::ifstream ifs( "data_to_harness.dat" , std::ifstream::in );ifs.read((char * )data_to_harness,number_of_elements*sizeof(float));ifs.close();
Write data from C++ program:
Datatype
float data_to_harness[number_of_elements];
std::ofstream ofs( "data_from_harness.dat" , std::ifstream::out );ofs.write((char * )data_to_harness,number_of_elements*sizeof(float));ofs.close();
Read the fata
Creating an implementation>cp kth_usrp_utilities/rx_60GHz.cpp green/rx_green.cpp
>cp kth_usrp_utilities/rx_60GHz.cpp green/tx_green.cpp
>cp kth_usrp_utilities/Makefile green/Makefile
green_signal_processing.cpp
green_signal_processing.hpp
Modify Makefile:
rx_green: rx_green.o green_signal_processing.o green_signal_processing.hpp
$(CXX) -o $@ $^ $(LDLIBS)
Modify rx_green.cpp:
#include “green_signal_processing.hpp”
Add parameters, Array to hold detected data?
save received data on disk.
Your signal processing implementationfunctions (objects?)
Tab
Modify rx_green.cppwhile (num_rx_samps<total_num_samps) {
num_rx_samps_latest_call=0; while (num_rx_samps_latest_call==0) { num_rx_samps_latest_call= rx_stream->recv(&buff_short[0],buffer_size, md, 3.0); }; if (num_rx_samps_latest_call!=buffer_size) { std::cerr << "I expect the buffer size to be always the same!"; exit(1); };
/* Process the just received buffer */
};
int i1=2*num_rx_samps; int i2=0; while ((i1<(int) (2*total_num_samps)) && (i2<2*buffer_size)) { storage_short[i1]=buff_short[i2]; i1++; i2++; }; num_rx_samps=num_rx_samps+num_rx_samps_latest_call; std::cout << "num_rx_samps=" << num_rx_samps << std::endl;
green_process_received_power(buff_short,detected_bits);
buff_short
Address Content Access
0x100 real[y[0]] buff_short[0]
0x102 imag[y[0]] buff_short[1]
0x104 real[y[1]] buff_short[3]
0x106 imag[y[1]] buff_short[4]
... ... ...
xx real[y[buffer_size-1]] buff_short[2*buffer_size-2]
xxx imag[y[buffer_size-1]] buff_short[2*buffer_size-1]
buff_short
std::complex *y=(std::complex *) buff_short;
[-2^15,2^15-1]
|y|>10000, distortion?
Debugging
Developing in Matlab – testing on real hardware (tx_60GHz.m, rx_60GHz.m)
printf, cout (yes – seriously).
#define DISPLAY_VALUE(X) std::cout << #X << "=" << X << std::endl ddd (GUI debugger)
Test important functions in harnesses:
Example harness.m/harness.cpp/square_elements_of_array
1. harness.m : Creates test data input and writes to file
2. harness.cpp: Read data from file and transform it and call square_elements_of_array
3. square_elements_of_array.cpp: Contains function to be tested.
4. harness.cpp: Write result on file.
5. harness.m: Read data from file.
6. Call the matlab reference implementation square_elements_of_array.m.
Look and run the example code!
Harness example Makefile
square_elements_of_array_debug.cpp: square_elements_of_array.cpp cp square_elements_of_array.cpp square_elements_of_array_debug.cppsquare_elements_of_array_debug.o: CXXFLAGS = -ggdb -Wallharness.o: CXXFLAGS = -ggdb -Wallharness: harness.o square_elements_of_array_debug.o $(CXX) -o $@ $^ $(LDLIBS)
Your case (proposal)
signal_process_green_debug.cpp: signal_processing_green.cpp cp signal_processing_green.cpp signal_process_green_debug.cppsignal_process_green_debug.o: CXXFLAGS = -ggdb -Wallharness1.o CXXFLAGS = -ggdb -Wallharness1: harness1.o signal_process_green_debug.o $(CXX) -o $@ $^ $(LDLIBS)
harness1.cpp:
#include “signal_processing_green.hpp”…… fs.read((char * ) data_to_be_encoded,number_of_elements*sizeof(char));……encode(data_to_encoded,encoded_data);……
Test e.g convolutional-encoder
Example session with ddd and harness
> ddd &
> file → open program → harness Mark line just before “std::cout << “dummy_string” Program → Run() → set “run with arguments” to e.g. “--no_elements=5” Klick step until the the pointer is just before.“// Save data to file” Write “data_to_harness” in uppermost window press “Print” then observe lowest window. Then change to data_to_harness[0] and press print. Then change to data_to_harness[0]@5.
Press kill. Program → Run() to first breakpoint. single-step (next) until you reach “square_elements_of_array”. Klick “Step” to enter square_elements_of_array.Write data_to_harness[0]@5 in the uppermost window. Press display.Klick Step and watch the contents of the display as you transverse through the array.
Kill the ddd if it hangs: killall -s 9 ddd
IT++: Example coded BPSK simulation
BPSK bpsk;
Convolutional_Code Code;
ivec generator(3);
generator(0)=0133;
generator(1)=0165;
generator(2)=0171;
code.set_generator_polynomials(generator, 7);
bvec bits=randb(100), encoded_bits decoded_bits;
vec tx_signal, rx_signal;
code.encode_tail(bits, encoded_bits);
tx_signal = bpsk.modulate_bits(encoded_bits);
rx_signal = tx_signal + sqrt(0.5)* (tx_signal.size());
code.decode_tail(rx_signal, decoded_bits);
IT++: Getting started
#include <itpp/itbase.h>
#include <itpp/itcomm.h>
#include <complex>
using namespace itpp;
int main( int argc, char *argv[])
{
cvec v1;
cvec v2;
cvec v3;
v1="(5,3),(-13,-4),(3,36)"; // (real,imag)
v2="(28,-13),(30,7),(-1,7)"; // (real,imag)
v3=v1+v2;
std::cout << "v3=" << v3 << std::endl;
}
g++ test.cpp -o test -litpp
code versioning systems
CVS, SVN, git, ….
purpose: Keep track of created textfiles (e.g. C++ code). Versions. Helps merge changes by multiple users.
We will use git: distributed versioning system … but
we will used in a centralized manner
Set up local repository (=local copy)
>git clone https://github.com/pzett/green.git green_alice
>cd green_alice
>git config –local user.email alice@kth.se
>git config -local user.name aliceg
Use same emailand username asyour github account
How we will workRepositorygreen
Alice:
* Implements or changes file1.cpp and file2.cpp
Updates repository:git add file1.cpp file2.cppgit commit -m “comment”git push….
Bob:
* Implements or changes file1.hpp and file2.hpp
Updates repository:git add file1.hpp file2.hppgit commit -m “comment”git push
file1.hpp file2.hpp
file1.cpp file2.cpp
git pull git pull
file1.hpp file2.hpp file1.cpp file2.cpp
Conflict resolution
Alice and Bob have clean updated local repositories. Alice modifies her file1.cpp Bob modifies his file1.cpp Bob does:
git add file1.cpp git commit -m “change initialization of i1” git push
Alice does:
git add file1.cpp git commit -m “I changed initialization of i1 to 2” git push
CONFLICT (content): Merge conflict in file1.cpp
Automatic merge failed; fix conflicts and then commit the result.
Response
Conflict resolution continued Alice opens file1.cpp:
<<<<<<< HEAD
i1=2;
=======
I1=1;
>>>>>>> 55f223d4ab24ae40f19ae551d51205b69a23177e
Alice and Bob discusses and finds that Alice was right. Alice removes Bobs code and pushes it.
Alice> git add file1.cppAlice> git commit -F .git/MERGE_MSGAlice> git pushBob> git pull Alice and Bob now has identical local repositories with Alice's code.
Alice's code
Bob's code
Assignment
I. Make a CW transmitter program which uses 25Msps sample rate and transmits a CW between -12.5 and 12.5MHz. The parameter freq define the frequency in MHz .
II. Make a receiver program with 25Msps rate which calculates the power of the input signal every second. The DC component should be removed.
III. Make receiver program with 25Msps rate, which calculates the power of the input signal every second at the output of 25 filters centered at frequency -12,-11,-10,...,12.
IV. Implement a non-trivial function relevant for your project, first in Matlab and then in C++, then verify it using the harness methodology.
top related