Sperimentiamo con il Software Defined Radio e GNU Radio

Abbiamo introdotto il paradigma Software Defined Radio, evidenziandone i vantaggi rispetto ai classici approcci hardware-based, come maggiore adattabilità, costi ridotti e scalabilità.

Abbiamo anche accennato all'esistenza di diversi strumenti, alcuni di natura commerciale, ed altri liberi, che permettono di sviluppare applicativi specificamente pensati per il signal processing in questo ambito. In particolare, in questo articolo tratteremo GNU Radio, uno strumento open, flessibile e completo, che può essere utilizzato praticamente su qualsiasi dispositivo, a patto che questo supporti una distribuzione Linux: scopriamolo insieme.

Introduzione

Uno degli errori commessi da chi è alle prime armi nel mondo della programmazione è (tentare di) reinventare la ruota: scrivere da zero un applicativo che svolga compiti più o meno articolati richiede competenze che, normalmente, vanno acquisite con impegno e dedizione (e, comunque, la mole di lavoro spesso risulta soverchiante). Pensiamo, ad esempio, alle librerie che ci permettono di far interagire Arduino con uno shield: scriverne una da zero è complesso, e basta fare un salto su GitHub per trovare soluzioni già pronte, che ci permetteranno di affinare le nostre conoscenze e, magari, una volta acquisita abbastanza esperienza, dare anche il nostro contributo allo sviluppo della libreria stessa.

Supponiamo, in tal senso, di voler sviluppare un applicativo da utilizzare per l'elaborazione di un segnale in un sistema SDR. Se lo sviluppassimo da zero, avremmo bisogno di implementare i meccanismi di I/O, i driver dei vari dispositivi, sviluppare l'interfaccia grafica, e via discorrendo. Bene, esiste un framework, rigorosamente open source, che fa tutto questo (e molto altro ancora) per noi: GNU Radio. In particolare, GNU Radio ci mette a disposizione una serie di moduli, ognuno dei quali contiene dei "mattoni", mediante i quali potremo costruire la nostra applicazione, a seconda delle nostre esigenze; è però importante sottolineare che GNU Radio non offre soluzioni preconfezionate, ma tocca a noi costruire un applicativo combinando i vari pezzi a disposizione.

Scopriamo assieme quali sono le opportunità che ci offre GNU Radio, illustrandone i principi mediante lo sviluppo di una semplice applicazione introduttiva. Una piccola nota: per seguire al meglio la restante parte del tutorial, è necessaria un pò di competenza con il linguaggio di programmazione Python; se è la prima volta che usate questo linguaggio, potete dare un'occhiata qui.

Up and running

Il primo passo è, ovviamente, installare GNU Radio. Il framework è disponibile per i principali sistemi operativi: la procedura di installazione è standard, e su Windows prevede l'utilizzo di un apposito installer, facilmente recuperabile dal sito ufficiale, mentre su distro Linux occorrerà utilizzare il package manager della distribuzione utilizzata. Ad esempio, su Ubuntu, basterà digitare da terminale:

$ sudo apt-get install gnuradio

A proposito: ecco una guida che può servirvi qualora abbiate delle difficoltà ad utilizzare la shell. Ovviamente, è anche possibile compilare direttamente dai sorgenti, ma, personalmente, consiglio di farlo solo in caso di esigenze particolari, o dell'assenza dell'apposito package nelle repository della propria distribuzione.

Noteremo, una volta terminata la procedura di installazione, che oltre al "core" di GNU Radio, saranno installati alcuni tool fondamentali, tra cui quello che utilizzeremo a breve, ossia GNU Radio Companion (GRC), uno strumento di progettazione interamente grafico, che può essere utilizzato per creare rapidamente dei prototipi e che, inoltre, genera codice Python, che potremo successivamente adattare alle nostre esigenze.

Sporchiamoci le mani!

Prima di iniziare a mettere le mani sul codice, è opportuno fare alcune importanti premesse. Un'applicazione GNU Radio è descritta da un grafo di flusso, i cui nodi sono chiamati blocchi. Ognuno dei blocchi effettua una specifica operazione sui dati: ad esempio, un blocco può filtrare un segnale passa basso, mentre un altro provocarne uno shift in frequenza. Si noti che ogni blocco deve essere (in linea di principio) atomico, e quindi effettuare un'unica operazione dei dati; tenere a mente questo principio è estremamente importante, specialmente quando se ne vanno a definire di nuovi, utilizzando ad esempio C o Python. I collegamenti tra blocchi (i "lati" del grafo) rappresentano il flusso dei dati: è quindi importante tenere in considerazione anche l'ordine con cui questi sono collegati.

Bene, è quindi giunto il momento di passare dalle parole ai fatti! Svilupperemo quello che viene considerato l'Hello World di un sistema di comunicazione radio: il dual tone generator, che genera due forme d'onda sinusoidali, a frequenze leggermente differenti, e le riproduce dagli speaker del nostro PC. Il suono riprodotto sarà quindi assimilabile a quello che può essere ascoltato quando si chiama un numero occupato.

Per prima cosa, apriamo GRC: da Windows, ci basterà cercare l'omonima applicazione, mentre, da Linux, dovremo aprire un terminale ed eseguire il seguente comando:

$ gnuradio-companion

Una volta avviato GRC, ci troveremo davanti alla schermata mostrata nella Figura 1.

radio

Figura 1: Schermata iniziale di GRC

L'interfaccia è abbastanza intuitiva, e comprende cinque sezioni. Nella parte superiore, abbiamo il classico menù, dal quale potremo selezionare le opzioni per la creazione e lettura di un nuovo progetto, oltre a quelle relative all'esecuzione ed al debug. Sulla destra avremo un elenco che mostrerà i blocchi disponibili, suddivisi per la funzione cui adempiono. Al centro avremo l'area di lavoro, nella quale possiamo già notare due blocchi, OptionsVariable, su cui ritorneremo a breve. In basso, infine, abbiamo la sezione di log, sulla sinistra, ed una sezione che ci mostra le variabili attualmente nell'area di lavoro, al centro.

In Figura 2 è mostrato ciò che vogliamo ottenere.

radio

Figura 2: Dual Tone Generator in GRC

Ok, ci sono un sacco di cose interessanti da mostrare, quindi, un passo alla volta.

Innanzitutto, GRC è un editor drag & drop: ciò significa che, per aggiungere e collegare i blocchi, ci basterà selezionare quello desiderato dall'elenco a destra e trascinarlo nella zona di lavoro. I blocchi andranno poi collegati cliccando sulle rispettive porte di ingresso e di uscita.

Abbiamo già accennato ai blocchi Options Variable. Nel primo, sono specificate alcune caratteristiche dell'applicazione, in particolare:

  • nome dell'applicazione (ID);
  • struttura del codice Python generato a partire dal grafo di flusso (Generate Options);
  • parametri per l'esecuzione del programma (Run Options).

Notiamo che, per quello che riguarda il campo Generate Options, abbiamo scelto No GUI: questo implica che il codice Python generato non debba gestire alcuna interfaccia grafica. Ciascun blocco Variable, invece, specifica una variabile globale; in particolare, notiamo le variabili samp_rate, pari a 32000, che rappresenta il tasso di campionamento dei nostri segnali, e ampl, pari a 0.1, che si riferisce alla loro ampiezza.

 

MAGGIORI APPROFONDIMENTI SULL'ARGOMENTO