people.kth.se
Download
Report
Transcript people.kth.se
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/tclcourse/emacs-tutorial.html
Coding language C++
The KTH USRP skeleton code and Matlab interface
“C++ primer” by Lippman and Lajoie, cplusplus.com
Command documentation (“help”) and source code.
Compiling source code:
g++ (http://gcc.gnu.org/),
make (https://www.gnu.org/software/make/)
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
Using (our) Matlab interface for USRP
On TX
computer:
Check that
tx.m,tx_60GHz.m
tx( Nsamples,RF_freq, X, ref_clk, gain,
tx_rate, LOoffset, low_res)
Recommendations:
Nsamples=length(X)
Nsamples=length(X)+guard
or
RF_freq=5.5e9 or 5.6e9
X: Signal to be transmitted (complex). RMS <=
5000.
ref_clk=0;
rx.m, rx_60GHz.m
X=rx(Nsamples,
RFfreq,ref_clk,g
ain,rx_rate,LOoff
set);
Compiling
Parameters, compilation flags, libraries
to link width
Compile source without Makefile:
g++ -o test test.cpp
The executable tx_60GHz depends on
tx_60GHz.o. Since there is a file tx_60GHz.cpp
in the folder, “make” understands that
it should compile it obtain tx_60GHz.o.
In our Makefile:
CXXFLAGS = -o3 -Wall -DNDEBUG
LDLIBS = -luhd -lboost_program_options
...
tx_60GHz: tx_60GHz.o
Passing command line parameters
to c++-program: classic way
#include <iostream>
#include <stdlib.h>
Program
int main(int argc, char **argv) {
double input=atof(argv[1]);
Execution
std::cout << “input=” << input << “\n”;
return 0;
};
Passing command line parameters to
c++program: boost::program_options
po::options_descrip
tion desc("Allowed
options");
Program
Execution
Calling program from Matlab
./harness ---dummy_fl=2.12
dummy_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:
Datatype
float
data_to_harness[number_of_elements];
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:
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
Your signal processing implementation
functions (objects?)
green_signal_processing.hpp
Modify Makefile:
Tab
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.
Modify rx_green.cpp
while (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 */
green_process_received_power(buff_short,detected_bits)
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;
buff_short
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]
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
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.cpp
square_elements_of_array_debug.o:
CXXFLAGS = -ggdb -Wall
harness.o:
CXXFLAGS = -ggdb -Wall
harness:
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.cpp
signal_process_green_debug.o:
CXXFLAGS = -ggdb -Wall
harness1.o
CXXFLAGS = -ggdb -Wall
harness1:
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));
…
…
Test e.g convolutionalencode(data_to_encoded,encoded_data);
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. “--
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;
g++ test.cpp
cvec
v2;-o test -litpp
cvec v3;
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 [email protected]
>git config -local user.name aliceg
Use same email
and username as
your github account
How we will work
Repository
green
file1.cpp file2.cpp
file1.hpp file2.hpp
Alice:
* Implements or changes file1.cpp
and file2.cpp
Updates repository:
git add file1.cpp file2.cpp
git commit -m “comment”
git push
….
git pull
file1.hpp file2.hpp
Bob:
* Implements or changes file1.hpp
and file2.hpp
Updates repository:
git add file1.hpp file2.hpp
git commit -m “comment”
git push
git pull
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:
Response
git add file1.cpp
git commit -m “I changed initialization of i1 to 2”
Conflict resolution continued
Alice opens file1.cpp:
<<<<<<< HEAD
i1=2;
Alice's code
=======
I1=1;
Bob's code
>>>>>>> 55f223d4ab24ae40f19ae551d51205b69a23177e
Alice and Bob discusses and finds that Alice was right. Alice
removes Bobs code and pushes it.
Alice> git add file1.cpp
Alice> git commit -F .git/MERGE_MSG
Alice> git push
Bob> git pull
Alice and Bob now has identical local repositories with Alice'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.